From 59869b83596f3f2c3916af45440046f1729c220d Mon Sep 17 00:00:00 2001 From: ohhamma Date: Wed, 21 Aug 2024 14:33:52 +0900 Subject: [PATCH] KL-153/feat: add Location header --- .../product/controller/ProductController.java | 18 +++++++++++++----- .../product/service/ProductServiceImpl.java | 4 ++-- .../controller/ProductControllerTest.java | 1 + .../integration/ProductIntegrationTest.java | 1 + 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/taco/klkl/domain/product/controller/ProductController.java b/src/main/java/taco/klkl/domain/product/controller/ProductController.java index 56998094..2007287a 100644 --- a/src/main/java/taco/klkl/domain/product/controller/ProductController.java +++ b/src/main/java/taco/klkl/domain/product/controller/ProductController.java @@ -1,10 +1,10 @@ package taco.klkl.domain.product.controller; +import java.net.URI; import java.util.Set; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -14,8 +14,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -86,11 +86,12 @@ public ProductDetailResponse findProductById( @PostMapping @Operation(summary = "상품 등록", description = "상품을 등록합니다.") - @ResponseStatus(HttpStatus.CREATED) - public ProductDetailResponse createProduct( + public ResponseEntity createProduct( @Valid @RequestBody ProductCreateUpdateRequest createRequest ) { - return productService.createProduct(createRequest); + ProductDetailResponse createdProduct = productService.createProduct(createRequest); + URI location = createResourceLocation(createdProduct.id()); + return ResponseEntity.created(location).body(createdProduct); } @PutMapping("/{productId}") @@ -111,4 +112,11 @@ public ResponseEntity deleteProduct( return ResponseEntity.noContent().build(); } + private URI createResourceLocation(final Long resourceId) { + return ServletUriComponentsBuilder + .fromCurrentRequest() + .path("/{productId}") + .buildAndExpand(resourceId) + .toUri(); + } } diff --git a/src/main/java/taco/klkl/domain/product/service/ProductServiceImpl.java b/src/main/java/taco/klkl/domain/product/service/ProductServiceImpl.java index 246b22fe..cf7c26f2 100644 --- a/src/main/java/taco/klkl/domain/product/service/ProductServiceImpl.java +++ b/src/main/java/taco/klkl/domain/product/service/ProductServiceImpl.java @@ -93,7 +93,7 @@ public PagedResponseDto findProductsByFilterOptionsAndSor public ProductDetailResponse findProductById(final Long id) throws ProductNotFoundException { final Product product = productRepository.findById(id) .orElseThrow(ProductNotFoundException::new); - return taco.klkl.domain.product.dto.response.ProductDetailResponse.from(product); + return ProductDetailResponse.from(product); } @Override @@ -105,7 +105,7 @@ public ProductDetailResponse createProduct(final ProductCreateUpdateRequest crea Set tags = createTagsByTagIds(createRequest.tagIds()); product.addTags(tags); } - return taco.klkl.domain.product.dto.response.ProductDetailResponse.from(product); + return ProductDetailResponse.from(product); } @Override diff --git a/src/test/java/taco/klkl/domain/product/controller/ProductControllerTest.java b/src/test/java/taco/klkl/domain/product/controller/ProductControllerTest.java index 8b014066..27194bb1 100644 --- a/src/test/java/taco/klkl/domain/product/controller/ProductControllerTest.java +++ b/src/test/java/taco/klkl/domain/product/controller/ProductControllerTest.java @@ -302,6 +302,7 @@ void testCreateProduct_ShouldReturnCreatedProduct() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(productCreateUpdateRequest))) .andExpect(status().isCreated()) + .andExpect(header().string("Location", containsString("/v1/products/"))) .andExpect(jsonPath("$.isSuccess", is(true))) .andExpect(jsonPath("$.data.id", is(productDetailResponse.id().intValue()))) .andExpect(jsonPath("$.data.name", is(productDetailResponse.name()))) diff --git a/src/test/java/taco/klkl/domain/product/integration/ProductIntegrationTest.java b/src/test/java/taco/klkl/domain/product/integration/ProductIntegrationTest.java index 3046a6e3..c1c7b980 100644 --- a/src/test/java/taco/klkl/domain/product/integration/ProductIntegrationTest.java +++ b/src/test/java/taco/klkl/domain/product/integration/ProductIntegrationTest.java @@ -98,6 +98,7 @@ public void testCreateProduct() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(new ObjectMapper().writeValueAsString(createRequest))) .andExpect(status().isCreated()) + .andExpect(header().string("Location", containsString("/v1/products/"))) .andExpect(jsonPath("$.isSuccess", is(true))) .andExpect(jsonPath("$.data.id", notNullValue())) .andExpect(jsonPath("$.data.name", is(createRequest.name())))