@@ -0,0 +1,72 @@
+package com.frame2.server.core.board.api;
+
+import com.frame2.server.core.board.application.ProductReviewService;
+import com.frame2.server.core.board.payload.request.ProductReviewModifyRequest;
+import com.frame2.server.core.board.payload.request.ProductReviewRequest;
+import com.frame2.server.core.board.payload.response.ProductReviewResponse;
+import com.frame2.server.core.support.annotations.Auth;
+import com.frame2.server.core.support.annotations.MemberOnly;
+import com.frame2.server.core.support.request.User;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/products/{saleProductId}/reviews")
+public class ProductReviewApi implements ProductReviewApiSpec {
+
+    private final ProductReviewService productReviewService;
+
+    // create
+    @Override
+    @MemberOnly
+    @PostMapping
+    public void createProductReview(
+            @Valid @RequestBody ProductReviewRequest productReviewRequest,
+            @Auth User user,
+            @PathVariable("saleProductId") Long saleProductId
+    ) {
+        productReviewService.productReviewCreate(productReviewRequest, user.id(), saleProductId);
+    }
+
+    // update
+    @Override
+    @MemberOnly
+    @PatchMapping("/{productReviewId}")
+    public void updateProductReview(
+            @Valid @RequestBody ProductReviewModifyRequest ProductReviewModifyRequest,
+            @Auth User user,
+            @PathVariable("productReviewId") Long productReviewId
+    ) {
+        productReviewService.productReviewModify(ProductReviewModifyRequest, productReviewId);
+    }
+
+    // delete
+    @Override
+    @MemberOnly
+    @DeleteMapping("/{productReviewId}")
+    public void deleteProductReview(@PathVariable("productReviewId") Long id, @Auth User user) {
+        productReviewService.remove(id);
+    }
+
+    // 단건 조회
+    @Override
+    @GetMapping("/{productReviewId}")
+    public ResponseEntity<ProductReviewResponse> getProductReview(@PathVariable("productReviewId") Long productReviewId) {
+        ProductReviewResponse productReviewResponse = productReviewService.getProductReview(productReviewId);
+        return ResponseEntity.ok().body(productReviewResponse);
+    }
+
+    // 한 상품에 대한 전체 리뷰 조회
+    @Override
+    @GetMapping
+    public ResponseEntity<List<ProductReviewResponse>> getProductReviewList(
+            @PathVariable("saleProductId") Long saleProductId) {
+        List<ProductReviewResponse> productReviewList = productReviewService.getProductReviewList(saleProductId);
+        return ResponseEntity.ok().body(productReviewList);
+    }
+}

리뷰: 단건 조회를 한 리뷰를 수정하는 것입니다.

일단 괄호는 지워야 하는게 맞는데 자꾸 이런 실수를 하네요.. 
리뷰 수정은 수정할 때 어떤 순서로 이루어 지는지를 생각해 봤는데요
1.먼저 단건 조회를 한다    /reviews/{productReviewId}
2. 단건 조회 화면에서 수정을 누른다.
3. 수정 화면에서 수정을 요청한다.   patch 요청 /reviews
3-1.  1번에서  productReviewId를 이미 가지고 있으니까 클라이언트에서 수정 요청 때 같이  값이 넘어오면 되지 않을까 하여 url에는 넣지 않았습니다.  

답변을 작성하면서 느꼈는데 이렇게 하면 url에 일관성이 없는 것 같긴 하네요
좀 더 명확하게 알기 위해서  @PatchMapping("/reviews/{productReviewId}") 로 수정하겠습니다