diff --git a/README.md b/README.md index 4e9f57f7e..27a1d56cb 100644 --- a/README.md +++ b/README.md @@ -115,3 +115,22 @@ HTTP 메시지를 주고받도록 구현한다. ## 6주차 0단계 - 기본 코드 준비 ### 기능 요구 사항 - 5주차 코드 옮겨오기 + +## 6주차 1단계 - API 명세 +### 기능 요구 사항 - 작성한 API 문서를 기반으로 팀 내 API 검토 및 통일 +1. 팀 내 일관된 기준을 정하여 API 명세 결정 +2. 클라이언트의 편의를 위한 API 명세 결정 + +## 6주차 2단계 - 배포하기 +### 기능 요구 사항 - 선물하기 서비스 배포 및 클라이언트와 연동 +1. 지속적인 배포를 위한 배포 스크립트 작성 +2. 클라이언트와 API 연동 시 발생하는 보안 문제에 대응 +3. 서버와 클라이언트의 Origin이 달라 요청을 처리할 수 없는 경우 해결 +4. HTTPS는 팀 내에서 논의 후 필요한 경우 적용 + +## 6주차 3단계 - 포인트 +### 기능 요구 사항 - 상품 구매에 사용할 수 있는 포인트 기능 구현 +1. 포인트는 사용자별로 보유 +2. 포인트 차감 방법 등 나머지 기능에 대해서는 팀과 논의하여 정책 결정 후 구현 +3. API 명세는 팀과 협의하여 걸정하고 구현 +4. 관리자 화면에서 포인트 충전 가능 \ No newline at end of file diff --git a/src/main/java/gift/config/WebConfig.java b/src/main/java/gift/config/WebConfig.java index 5b1ee7751..7ecdef55e 100644 --- a/src/main/java/gift/config/WebConfig.java +++ b/src/main/java/gift/config/WebConfig.java @@ -46,8 +46,8 @@ public void addInterceptors(InterceptorRegistry registry) { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") - .allowedOrigins("http://localhost:8080") - .allowedMethods("GET", "POST", "PUT", "DELETE") + .allowedOrigins("*") + .allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); diff --git a/src/main/java/gift/controller/MemberController.java b/src/main/java/gift/controller/MemberController.java index 375ab2001..60c8d8e1b 100644 --- a/src/main/java/gift/controller/MemberController.java +++ b/src/main/java/gift/controller/MemberController.java @@ -1,6 +1,7 @@ package gift.controller; import gift.dto.MemberDTO; +import gift.dto.MemberResponse; import gift.model.Member; import gift.service.MemberService; import gift.util.JwtUtil; @@ -12,9 +13,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import java.util.HashMap; -import java.util.Map; - @RestController @RequestMapping("/api/members") public class MemberController { @@ -34,9 +32,7 @@ public ResponseEntity registerMember(@Valid @RequestBody MemberDTO memberDTO) MemberDTO savedMember = memberService.register(memberDTO); String token = jwtUtil.generateToken(savedMember.getEmail()); - Map response = new HashMap<>(); - response.put("email", savedMember.getEmail()); - response.put("token", token); + MemberResponse response = new MemberResponse(savedMember.getEmail(), token); return ResponseEntity.status(HttpStatus.CREATED).body(response); } @@ -48,9 +44,7 @@ public ResponseEntity login(@Valid @RequestBody MemberDTO loginDetails) { String password = loginDetails.getPassword(); String token = memberService.login(email, password); - Map response = new HashMap<>(); - response.put("email", email); - response.put("token", token); + MemberResponse response = new MemberResponse(email, token); return ResponseEntity.ok(response); } diff --git a/src/main/java/gift/controller/ProductRestController.java b/src/main/java/gift/controller/ProductRestController.java index 166231786..660f70768 100644 --- a/src/main/java/gift/controller/ProductRestController.java +++ b/src/main/java/gift/controller/ProductRestController.java @@ -1,6 +1,7 @@ package gift.controller; import gift.dto.ProductDTO; +import gift.dto.ProductRequest; import gift.service.ProductService; import io.swagger.v3.oas.annotations.Operation; import jakarta.validation.Valid; @@ -27,28 +28,12 @@ public ProductRestController(ProductService productService) { @Operation(summary = "모든 상품 가져오기") @GetMapping - public ResponseEntity> getAllProducts( - @RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "10") int size, - @RequestParam(defaultValue = "id,asc") String[] sort, - @RequestParam(required = false) Long categoryId) { - - Pageable pageable = PageRequest.of(page, size, Sort.by(getSortOrders(sort))); - Page products = productService.getAllProducts(pageable, categoryId); + public ResponseEntity> getAllProducts(@Valid ProductRequest productRequest) { + Pageable pageable = PageRequest.of(productRequest.getPage(), productRequest.getSize(), productRequest.getSortOrders()); + Page products = productService.getAllProducts(pageable, productRequest.getCategoryId()); return ResponseEntity.ok(products); } - private List getSortOrders(String[] sort) { - return Arrays.stream(sort) - .map(this::createSortOrder) - .collect(Collectors.toList()); - } - - private Sort.Order createSortOrder(String sortOrder) { - String[] parts = sortOrder.split(","); - return new Sort.Order(Sort.Direction.fromString(parts[1]), parts[0]); - } - @Operation(summary = "ID로 상품 가져오기") @GetMapping("/{id}") public ResponseEntity getProductById(@PathVariable Long id) { diff --git a/src/main/java/gift/dto/MemberResponse.java b/src/main/java/gift/dto/MemberResponse.java new file mode 100644 index 000000000..c31638604 --- /dev/null +++ b/src/main/java/gift/dto/MemberResponse.java @@ -0,0 +1,20 @@ +package gift.dto; + +public class MemberResponse { + + private String email; + private String token; + + public MemberResponse(String email, String token) { + this.email = email; + this.token = token; + } + + public String getEmail() { + return email; + } + + public String getToken() { + return token; + } +} diff --git a/src/main/java/gift/dto/ProductRequest.java b/src/main/java/gift/dto/ProductRequest.java new file mode 100644 index 000000000..e5446461b --- /dev/null +++ b/src/main/java/gift/dto/ProductRequest.java @@ -0,0 +1,48 @@ +package gift.dto; + +import org.springframework.data.domain.Sort; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public class ProductRequest { + + private final int page; + private final int size; + private final String[] sort; + private final Long categoryId; + + public ProductRequest(int page, int size, String[] sort, Long categoryId) { + this.page = page; + this.size = size; + this.sort = sort != null ? sort : new String[]{"id", "asc"}; // 기본 정렬 값 + this.categoryId = categoryId; + } + + public int getPage() { + return page; + } + + public int getSize() { + return size; + } + + public String[] getSort() { + return sort; + } + + public Long getCategoryId() { + return categoryId; + } + + public Sort getSortOrders() { + return Sort.by( + Arrays.stream(sort) + .map(s -> { + String[] parts = s.split(","); + return new Sort.Order(Sort.Direction.fromString(parts[1]), parts[0]); + }) + .collect(Collectors.toList()) + ); + } +}