DTO
를 파라미터 받게 해야 한다.
→ 아래처럼 엔티티
자체에 API 검증
을 위한 로직(@NotEmpty
)을 구현해놓고, 엔티티
를 외부에서 받은 데이터(JSON
)을 바인딩
하기 위해 파라미터
로 직접 사용해선 절대 안된다 !
→ 쉽게 말하면, 엔티티
를 외부로 노출시키지 말자 !엔티티
를 RequestBody
에 직접 매핑하게 되면 ?
→ 엔티티
와 API
를 일대일 관계
로 매핑한 것이나 마찬가지이다 !
엔티티
를 위한 API
가 다양하게 만들어지는데, 한 엔티티
에 각각의 API
를 위한 모든 요청 요구사항을 담기 어렵다.엔티티
가 변경하게 되면 API 스펙
까지 변경되기 때문에 골치 아파진다.// MemberApiController
@PostMapping("/api/v1/members")
public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) {
Long id = memberService.join(member);
return new CreateMemberResponse(id);
}
@Data
static class CreateMemberResponse {
private Long id;
public CreateMemberResponse(Long id) {
this.id = id;
}
}
// Member.java
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private Long id;
@NotEmpty
private String name;
...
엔티티
대신에 DTO
를 RequestBody
에 매핑해주는 방식, 즉 엔티티
를 외부로 노출시키지 않고 API
를 만드는 방식이 정석이다 !
→ 별도의 클래스를 따로 생성해줘야 하긴 하지만, 유지보수를 위해 !
엔티티
와 프레젠테이션 계층(
@Controller)
을 위한 로직을 분리 가능하다.엔티티
와 API 스펙(
@NotEmpty)
을 명확하게 분리 가능하다.@PostMapping("/api/v2/members")
public CreateMemberResponse saveMemberV2(@RequestBody @Valid CreateMemberRequest request) {
Member member = new Member();
member.setName(request.getName());
Long id = memberService.join(member);
return new CreateMemberResponse(id);
}
@Data
static class CreateMemberRequest {
@NotEmtpy
private String name;
}
‣
PATCH
나 POST
를 사용하는 것이 RESTful
!PUT
은 전체 업데이트를 할 때 사용하는 것이 맞다 !