API 개발 기본

이가현·2022년 11월 4일
0

회원 등록 API

잘못된 방법 ( 요청 값으로 Member 엔티티를 직접 받음. )

@PostMapping("/api/v1/members")
public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member)
{
	Long id = memberService.join(member);
    return new CreateMemberResponse(id);
}

여러 곳에서 수정될 가능성이 있는 Entity가 바뀜으로 인해서
만들어놓은 api스펙이 변경될 수 있도록 하면 안된다.
-> ⭕️ API 요청 스펙에 맞추어 별도의 DTO를 파라미터로 받는다.

-> 파라미터로 넘어오는 값이 무엇인지 확실히 알 수 있음 !
-> 유지보수에 유리함.

@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 {
	private String name;
}

❗️❗️ 실무에서는 엔티티를 API 스펙에 노출하면 안된다!

회원 수정 API

회원 조회와 똑같이 DTO를 요청 파라미터에 넘겨준다.

@PostMapping("/api/v2/members/{id}") // 부분 업데이트를 하려면 post나 patch를 사용하는 것이 restful한 방법.
public UpdateMemberResponse updateMemberV2(@PathVariable("id") Long id, @RequestBody @Valid UpdateMemberRequest request) {
        memberService.update(id, request.getName());
        Member findMember = memberService.findOne(id); // 커맨드와 쿼리를 구분하기 위한 코드
        return new UpdateMemberResponse(findMember.getId(), findMember.getName());
}
public class MemberService {
        private final MemberRepository memberRepository;
     	
        // 변경 감지를 이용해서 데이터 수정함.
		@Transactional
        public void update(Long id, String name) {
            Member member = memberRepository.findOne(id);
            member.setName(name);
        }
}

회원 조회 API

🔴 다양한 API 요구에 따라서 유연하게 데이터를 주고받기 위해서
응답 값으로 엔티티를 직접 외부에 노출하지 않고,
별도의 DTO를 반환해야 한다.

@GetMapping("/api/v2/members")
public Result membersV2() {
	List<Member> findMembers = memberService.findMembers(); // 엔티티 -> DTO 변환
    List<MemberDto> collect = findMembers.stream()
    	.map(m -> new MemberDto(m.getName()))
        .collect(Collectors.toList());
    return new Result(collect);  // 컬렉션을 감싸서 향후 필요한 필드 추가 가능
}
@Data
@AllArgsConstructor
static class Result<T> {
	private T data;
}

Application.yml 에서

ddl-auto:None

위 코드 추가
-> 한번 데이터를 넣어놓으면 테이블을 들어가지 않고 계속해서 db에 있는 데이터들을 쓸 수 있다.

0개의 댓글