API 개발 ‐ 주문 조회 API 개발시 주의사항(다대일) - dnwls16071/Backend_Study_TIL GitHub Wiki

📚 API 개발 - V1(생성)

// Member 엔티티를 파라미터에
@PostMapping("/api/v1/members")
public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) {
	Long id = memberService.join(member);
	return new CreateMemberResponse(id);
}

@Data
static class CreateMemberRequest {

	@NotEmpty
	private String name;
}

@Data
@AllArgsConstructor
static class CreateMemberResponse {

	private Long id;
}
  • 요청 값으로 Member 엔티티를 직접 받는다.
  • 엔티티에 프레젠테이션 계층을 위한 로직이 추가된다. → 분리가 되지 않고 결국 API 스펙이 변할 우려가 있다.
  • 결론 : 엔티티 파라미터 (X) & 요청 스펙에 맞추어 커스텀으로 구성한 DTO 파라미터 (O)

📚 API 개발 - V2(생성)

@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);
}
  • 엔티티 - 도메인(Domain)
  • 컨트롤러 - 프레젠테이션(Presentation)
  • 이 두 가지의 명확한 분리가 가능하며 엔티티가 변하더라도 API 스펙은 변하지 않는다.

📚 API 개발 - V2(수정)

@PutMapping("/api/v2/members/{id}")
public UpdateMemberResponse updateMemberV2(@PathVariable(name = "id") Long id,
					   @RequestBody @Valid UpdateMemberRequest request) {
	memberService.update(id, request.getName());

	Member findMember = memberService.findOne(id);
	return new UpdateMemberResponse(findMember.getId(), findMember.getName());
}

@Data
static class UpdateMemberRequest {

	private String name;
}

@Data
@AllArgsConstructor
static class UpdateMemberResponse {

	private Long id;
	private String name;
}

@Transactional
public void update(Long id, String name) {
    Member member = memberRepository.findOne(id);
    member.setName(name);
}
  • 회원 수정 역시 엔티티 대신 DTO를 파라미터에 넣는다.
  • @PutMapping : 전체 업데이트, @PatchMapping : 일부 업데이트
  • 식별자를 통해 DB로부터 조회하여 JPA의 1차 캐시로 가져온 후(영속 상태) Dirty Checking(더티 체킹)을 통해 변경한다.

📚 API 개발 - V1(조회)

@GetMapping("/api/v1/members")
public List<Member> membersV1() {
	return memberService.findMembers();
}
  • 응답 값으로 엔티티를 직접 외부에 노출한다.
  • 예를 들어, 회원 목록만을 조회하고 싶다면 불필요하게 주문 내역 등도 같이 조회가 된다.
  • API 응답 스펙에 맞추어 별도의 DTO를 반환하는 것이 좋다.

📚 API 개발 - V2(조회)

@GetMapping("/api/v2/members")
public Result membersV2() {
	List<Member> members = memberService.findMembers();
	List<MemberDto> list = members.stream().map(member -> new MemberDto(member.getName())).toList();
	return new Result(list);
}

@Data
@AllArgsConstructor
static class MemberDto {

	private String name;
}

@Data
@AllArgsConstructor
static class Result<T> {

	private T data;
}
  • 응답 값으로 엔티티가 아닌 별도의 DTO를 만들어 반환한다.
⚠️ **GitHub.com Fallback** ⚠️