인프런 커뮤니티 질문&답변

zzzzz님의 프로필 이미지

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

MemberApiControllerv1질문있습니다.

작성

·

159

·

수정됨

0

package jpabook.jpashop.domains;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

//import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
public class Member {

    @Id
    @GeneratedValue
    @Column(name = "member_id")
    private Long id;

    private String name;

    @Embedded
    private Address address;

    @JsonIgnore
    @OneToMany(mappedBy = "member")
    private List<Order> orders = new ArrayList<>();
}

@RequiredArgsConstructor
@RestController
public class MemberApiController {
    private final MemberService memberService;
    @PostMapping()
    public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member){//jason데이터를 멤버로 쫙 바꿔줌(맵핑해줌_))
        Long id = memberService.join(member);
        return new CreateMemberResponse(id);
    }

    @Data
    static class CreateMemberResponse{
        private Long id;

        public CreateMemberResponse(Long id) {
            this.id = id;
        }


    }

}
  1. class Member에 getter,setter가 들어가 있는데 class MemberApiController에 왜 아래처럼 생성자를 생성해주는건가요?

        public CreateMemberResponse(Long id) {
            this.id = id;
        }

2. save함수는 아래에도 있는데 굳이 saveMemberV1 할 이유가 있나요? 혹시 api를 만들때는 엔티티매니저가 사용이 안되나요?

public class MemberRepository {
    //    @PersistenceContext//스프링이 엔티티 매니저를 만들면서 주입시켜주게 됨.
    private final EntityManager em;

    public void save(Member member) {
        em.persist(member);
    }

3 해당 강의에서 중간중간에 엔티티를 변경 즉 name->username으로 변경 시 api오류가나온다고 하셨는데요. 그런데 아래 코드 v1버전 중 CreateMemberResponse 매개변수에Member member가 주어지는데요. 생성자인 CreateMemberResponse(Long id)가 id만 받아와 지는데, 이 id가 (name이 아닌 id만 받아옴) member의 id기준으로 member의 전체 객체가 받아와져서 그러는건가요?

package jpabook.jpashop.api;

import jakarta.validation.Valid;
import jpabook.jpashop.Service.MemberService;
import jpabook.jpashop.domains.Member;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;


@RequiredArgsConstructor
@RestController
public class MemberApiController {
    private final MemberService memberService;
    @PostMapping("/api/v1/members")
    public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member){//jason데이터를 멤버로 쫙 바꿔줌(맵핑해줌_))
        Long id = memberService.join(member);
        return new CreateMemberResponse(id);
    }

    @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;//<-강의 중반주에 adreess넣을지 말지 하는 부분이 있었는데요. 만약 adress를 넣는다면,  member.setadress(request.getadress());를 안넣게되면 에러인가요?
    }

    @Data
    static class CreateMemberResponse{
        private Long id;

        public CreateMemberResponse(Long id) {
            this.id = id;
        }


    }

}

.

답변 2

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. zzzzz님

AI 인턴의 답에 추가로 3번의 경우를 답을 드리겠습니다.

CreateMemberResponse는 응답을 뜻합니다. 필요한 응답 데이터가 더 있다면 필드를 추가하고 값을 넣으면 됩니다. 요청의 경우 CreateMemberRequest를 사용합니다. 사용자의 요청 데이터를 추가로 받아야 한다면 여기에 필드를 추가하면 됩니다.

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다.

1. 생성자 사용 이유

CreateMemberResponse 클래스의 생성자를 별도로 정의한 이유는 데이터 응답 구조의 명확성 및 확장성을 위함입니다. 이 생성자는 API 응답 시 ID 값만 반환하기 위한 응답 DTO(Dara Transfer Object)의 역할을 수행합니다. 이렇게 별도의 DTO 클래스를 정의하여 사용하는 것은 엔티티(Member 클래스) 직접 반환을 피하고, 클라이언트에 반환되는 데이터를 유연하게 관리할 수 있게 하는 일반적인 패턴입니다. 엔티티의 구조가 변경되더라도 API 응답 구조를 유지할 수 있는 장점이 있습니다.

이와 관련된 상세한 설명은 “return new CreateMemberResponse(id); 필요성”에서 찾아볼 수 있습니다. 이 게시물에서는 API 응답의 데이터 구조를 CreateMemberResponse를 통해 JSON 형태로 관리하는 이유에 대해 설명하고 있습니다.

2. saveMemberV1 사용 이유 및 엔티티 매니저 사용 여부

saveMemberV1 함수는 API를 통해 클라이언트로부터 받은 요청을 처리하는 컨트롤러 내의 메소드입니다. MemberRepositorysave 메소드와는 다른 역할을 수행합니다. MemberRepositorysave는 단순히 멤버 엔티티를 데이터베이스에 저장하는 역할을 하며, MemberApiControllersaveMemberV1은 클라이언트로부터 요청 받은 데이터를 처리하고, 데이터를 저장한 다음, 그 결과를 클라이언트에게 반환하는 과정을 수행합니다.

API를 만들 때는 엔티티 매니저를 사용할 수 있으며, 실제로 MemberRepository에서 엔티티 매니저를 사용하여 데이터베이스에 저장하는 로직을 확인할 수 있습니다. API 컨트롤러에서 MemberService와 같은 서비스 계층을 통해 비즈니스 로직을 수행하는 것은 일반적으로 권장되는 구조입니다. 이는 레이어드 아키텍처를 따르면서 각 계층(레이어)의 책임을 분리하기 위함입니다.

이와 관련된 개념은 상세하게 다룬 게시물이 없어 직접적인 링크를 제공하지는 못하지만, 스프링 및 JPA를 사용한 백엔드 개발의 기본적인 패턴과 설계 원칙을 더 학습하시면 도움이 될 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

zzzzz님의 프로필 이미지

작성한 질문수

질문하기