π― CRUD API Request/Response Body μ€κ³ μλ²½ κ°μ΄λ
π€ μ μ΄ κ°μ΄λλ₯Ό λ§λ€μλ?
Java Spring λ°±μλ νλ‘μ νΈμμ API λͺ μΈμλ₯Ό μμ±νλ κ³Όμ μμ, CRUDμ Request/Response Bodyλ₯Ό μ΄λ»κ² μ€κ³ν΄μΌ νλμ§ λͺ νν μμΉκ³Ό ν¨ν΄μ μ΄ν΄νμ§ λͺ»ν΄ μ 리ν μ€μ κ°μ΄λμ λλ€.
π― νμ΅ λͺ©ν
RESTful API μ€κ³μ ν΅μ¬μΈ CRUD κ° κΈ°λ₯λ³ Request/Response Body μμ± μμΉκ³Ό ν¨ν΄μ μλ²½ν λ§μ€ν°νμ!
π λͺ©μ°¨
- RESTful API Body μ€κ³μ ν΅μ¬ μμΉ
- CRUDλ³ Request/Response Body ν¨ν΄
- Spring Boot μ€μ μ μ© μμ
- API λͺ μΈμ μμ± μ²΄ν¬λ¦¬μ€νΈ
π¨ RESTful API Body μ€κ³μ ν΅μ¬ μμΉ
π‘ λμμΉ: βμ΅μνμ μ λ³΄λ‘ λͺ ννκ² μν΅νλ€β
RESTful APIμ Body μ€κ³λ κ° HTTP Methodμ λ³Έλ λͺ©μ μ λ§μΆ° νμν μ λ³΄λ§ μ£Όκ³ λ°λ κ²μ΄ ν΅μ¬μ λλ€.
π HTTP Methodλ³ Body μ¬μ© μμΉ
HTTP Method | Request Body | Response Body | ν΅μ¬ μμΉ |
---|---|---|---|
POST π | β νμ | β νμ | μμ±μ νμν λͺ¨λ μ 보 β μμ ν μμ± κ²°κ³Ό |
GET π | β μ¬μ© μν¨ | β νμ | URL νλΌλ―Έν°λ‘ 쑰건 β μ‘°ν κ²°κ³Ό λ°ν |
PATCH/PUT βοΈ | β νμ | β νμ | λ³κ²½ν μ λ³΄λ§ β μμ ν μμ κ²°κ³Ό |
DELETE ποΈ | β μ¬μ© μν¨ | β λΉμλ | URLλ‘ μλ³ β 204 μν μ½λλ‘ μ±κ³΅ νμ |
π CRUDλ³ Request/Response Body ν¨ν΄
π CREATE (POST) - μλ‘μ΄ λ¦¬μμ€ μμ±
π― μ€κ³ μμΉ
- Request: μλ²κ° μλ μμ±νλ κ°(ID, μμ±μΌμ)μ μ μΈν λͺ¨λ νμ μ 보
- Response: μλ²μμ μμ±λ κ°μ ν¬ν¨ν μμ ν 리μμ€ μν
π» μμ: μν λ±λ‘ API
POST /api/products
π€ Request Body
{
"productName": "μ μ ν λͺ©μ₯ μ°μ 1L",
"productSaleCost": 2500,
"initialStockCount": 50,
"expirationDate": "2025-12-31"
}
π₯ Response Body (201 Created)
{
"productId": "PROD-001",
"productName": "μ μ ν λͺ©μ₯ μ°μ 1L",
"productSaleCost": 2500,
"totalStockCount": 50,
"expirationDate": "2025-12-31",
"createdAt": "2025-08-09T10:30:00",
"updatedAt": "2025-08-09T10:30:00",
"status": "ACTIVE"
}
π READ (GET) - 리μμ€ μ‘°ν
π― μ€κ³ μμΉ
- Request: Body μ¬μ©νμ§ μμ, λͺ¨λ 쑰건μ URL νλΌλ―Έν°λ‘
-
Response: λ¨μΌ κ°μ²΄
{}
λλ λ°°μ΄[]
ννλ‘ λ°ν
π» μμ: μν μ‘°ν API
λ¨μΌ μν μ‘°ν
GET /api/products/PROD-001
π₯ Response Body (200 OK)
{
"productId": "PROD-001",
"productName": "μ μ ν λͺ©μ₯ μ°μ 1L",
"productSaleCost": 2500,
"totalStockCount": 50,
"status": "ACTIVE"
}
μν λͺ©λ‘ μ‘°ν
GET /api/products?name=μ°μ &status=ACTIVE&page=0&size=10
π₯ Response Body (200 OK)
{
"content": [
{
"productId": "PROD-001",
"productName": "μ μ ν λͺ©μ₯ μ°μ 1L",
"productSaleCost": 2500,
"status": "ACTIVE"
},
{
"productId": "PROD-002",
"productName": "μ μ§ μ°μ 500ml",
"productSaleCost": 1800,
"status": "ACTIVE"
}
],
"totalElements": 2,
"totalPages": 1,
"currentPage": 0
}
βοΈ UPDATE (PATCH/PUT) - 리μμ€ μμ
π― μ€κ³ μμΉ
- PATCH: λ³κ²½ν νλλ§ μ μ‘ (λΆλΆ μ λ°μ΄νΈ)
- PUT: 리μμ€ μ 체 κ΅μ²΄
- Response: μμ μλ£λ μ 체 리μμ€ μν
π» μμ: μν μμ API
PATCH /api/products/PROD-001
π€ Request Body
{
"productSaleCost": 2800,
"totalStockCount": 30
}
π₯ Response Body (200 OK)
{
"productId": "PROD-001",
"productName": "μ μ ν λͺ©μ₯ μ°μ 1L",
"productSaleCost": 2800,
"totalStockCount": 30,
"expirationDate": "2025-12-31",
"updatedAt": "2025-08-09T15:45:00",
"status": "ACTIVE"
}
ποΈ DELETE - 리μμ€ μμ
π― μ€κ³ μμΉ
- Request: Body μ¬μ©νμ§ μμ
- Response: λΉ Body + 204 No Content μν μ½λ
π» μμ: μν μμ API
DELETE /api/products/PROD-001
π₯ Response (204 No Content)
(λΉμ΄μμ)
π Spring Boot μ€μ μ μ© μμ
π νλ‘μ νΈ κ΅¬μ‘°μμ DTO νμ©
// Request DTO
@Data
@NoArgsConstructor
public class ProductCreateRequest {
@NotBlank(message = "μνλͺ
μ νμμ
λλ€")
private String productName;
@Min(value = 0, message = "κ°κ²©μ 0 μ΄μμ΄μ΄μΌ ν©λλ€")
private Integer productSaleCost;
@Min(value = 0, message = "μ¬κ³ λ 0 μ΄μμ΄μ΄μΌ ν©λλ€")
private Integer initialStockCount;
@Future(message = "μ ν΅κΈ°νμ λ―Έλ λ μ§μ¬μΌ ν©λλ€")
private LocalDate expirationDate;
}
// Response DTO
@Data
@Builder
public class ProductResponse {
private String productId;
private String productName;
private Integer productSaleCost;
private Integer totalStockCount;
private LocalDate expirationDate;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private ProductStatus status;
}
π― Controllerμμμ νμ©
@RestController
@RequestMapping("/api/products")
public class ProductController {
@PostMapping
public ResponseEntity<ProductResponse> createProduct(
@Valid @RequestBody ProductCreateRequest request) {
ProductResponse response = productService.createProduct(request);
return ResponseEntity.status(HttpStatus.CREATED).body(response);
}
@GetMapping("/{productId}")
public ResponseEntity<ProductResponse> getProduct(
@PathVariable String productId) {
ProductResponse response = productService.getProduct(productId);
return ResponseEntity.ok(response);
}
@PatchMapping("/{productId}")
public ResponseEntity<ProductResponse> updateProduct(
@PathVariable String productId,
@RequestBody ProductUpdateRequest request) {
ProductResponse response = productService.updateProduct(productId, request);
return ResponseEntity.ok(response);
}
@DeleteMapping("/{productId}")
public ResponseEntity<Void> deleteProduct(@PathVariable String productId) {
productService.deleteProduct(productId);
return ResponseEntity.noContent().build();
}
}
β API λͺ μΈμ μμ± μ²΄ν¬λ¦¬μ€νΈ
π Request Body 체ν¬ν¬μΈνΈ
- POST: μλ μμ± κ°(ID, μμ±μΌμ) μ μΈν λͺ¨λ νμ μ 보 ν¬ν¨
- GET/DELETE: Body μ¬μ©νμ§ μμ
- PATCH: λ³κ²½ν νλλ§ ν¬ν¨
- PUT: μ 체 리μμ€ μ 보 ν¬ν¨
-
Validation:
@Valid
,@NotNull
λ± κ²μ¦ μ΄λ Έν μ΄μ μ μ©
π€ Response Body 체ν¬ν¬μΈνΈ
- POST/PATCH/PUT: μμ ν 리μμ€ μν λ°ν
-
GET: λ¨μΌ κ°μ²΄
{}
λλ λͺ©λ‘ λ°°μ΄[]
λ°ν - DELETE: λΉ Body + 204 μν μ½λ
-
νμ΄μ§:
content
,totalElements
,totalPages
λ± λ©νλ°μ΄ν° ν¬ν¨ - μλ¬ μλ΅: μΌκ΄λ μλ¬ μλ΅ νμ μ μ©
π― κ³΅ν΅ μ€κ³ μμΉ
- μΌκ΄μ±: νλ‘μ νΈ μ 체μμ λμΌν λ€μ΄λ° 컨벀μ μ¬μ©
- 보μ: λ―Όκ°ν μ 보(ν¨μ€μλ, ν ν° λ±) μλ΅μμ μ μΈ
- μ±λ₯: λΆνμν νλ μ μΈ, νμμ λ³λ API μ 곡
- λ¬Έμν: Swagger/OpenAPI λ±μ νμ©ν λͺ μΈμ μλν
π‘ ν΅μ¬ μ 리
π― RESTful API Body μ€κ³μ ν΅μ¬
- κ° HTTP Methodμ λͺ©μ μ λ§λ Body μ€κ³
- Requestλ μ΅μν, Responseλ μμ νκ²
- μΌκ΄λ ν¨ν΄μΌλ‘ μμΈ‘ κ°λ₯ν API
- Spring Bootμ DTO/Entity λΆλ¦¬ μμΉ μ€μ
μ΄μ Java Spring λ°±μλ νλ‘μ νΈμμ μμ μκ² API λͺ μΈμλ₯Ό μμ±ν μ μμ κ±°μμ! π
μ΄ κ°μ΄λκ° λμμ΄ λμλ€λ©΄, λ€μμλ μλ¬ μ²λ¦¬μ μν μ½λ νμ©λ²λ μ 리ν΄λ³΄κ² μ΅λλ€! π