20210823 til - DTO와 spring의 유용한 Annotations

Sorbet·2021년 8월 23일
0

1) DTO 관리하기

결론 : DTO와 엔티티는 분리하고, 응답용과 요청용도 따로 만드는게 좋다

  • 모두가 행복하기 위해서는 세가지(엔티티 + 최소2종의 DTO) 가 필요하다
    • Entity(Member) : 데이터가 저장되는 클래스
    • EntityDtoRequest(MemberDtoRequest) : Post 요청시에 받아야 하는 데이터
    • EntityDtoResponse(MemberDtoResponse) : GET 요청시에 응답해줘야 하는 데이터
  • 굳~~이 추가해야된다면
    • EntityDtoResponseSimple : 최소정보만 전달해주는 심플 응답
    • EntityDtoResponseDetail : 모든 데이터를 전달해주는 디테일 응답

예를들어

  • Member로 예시를 들어보면

    • Entity는 (Member Class, name, age, ) : 저장해야되는 값들
    • MemberDtoRequest : 프론트(클라이언트)가 보내줘야하는 값들만
      • CreatedAt 같은 필드는 저장해야하지만, 클라이언트가 보내주지 말고 백단에서 처리
      • isDeleted : 이런필드 받을필요가 없는게 삭제된걸 POST한다는게 말이 안됨
      • Id 프론트엔드가 알려줄수가 없다!
    • MemberDtoResponse : 서버에서 보내줘야 하는 값들
      • 예를들어 맴버의 최근1년 구매한 총액을 원한다면 이건 받거나 저장하는게 아니라 필요할때 계산해서 보내줘야함
      • id 꼭필요하다!
  • 아무튼 저 세가지 같지가 않아 같게 했다가는 (프론트엔드 개발자 && 기획자 선생님들의) 민원 오지게먹고 다 뜯어고치게 되어 있다

    • 그리고 또 나중에 프론트엔드에서 보여줘야하는 값하나 추가해줘야하는데 엔티티를 수정하면 엄청난 대공사인데
    • DtoResponse에 필드하나 추가해주는건 편하다 >> 유연성
  • 언제나 고객들은 자신들도 뭘 원하는지 모른다

    • 완공된 건물이 너무 마음에 드는데 각도를 3도만 돌려달라는 요청을 받을수 있다
    • 실제로 3도를 돌리진 못해도 클라이언트가 원하는게 뭐고 문제가 어디인지 파악해서 대안을 제시하고 수용하기 위해서는 최대한의 유연함을 확보해야 하는데
    • 클라이언트의 니즈가 3도 옆의 산을 좀더 잘 바라보고 싶다? 창문을 좀더 탁 트이는 통유리로 교체해서 전망을 좋게 만들어줄수 있어야하고
    • 방의 창문을 3도정도 돌려달라는게 낮에 너무 밝아서 그런거라면 건물을 3도 돌리는게 아니라 암막커튼을 달아줘서 해결하면 된다
  • 이외에도 뷰 결합도를 낮추고, 보안을 좋게한다

- 예시1 : 베이스볼 게임 in 코쿼
  - 입력은 : 볼/스트라이크/안타
  - 리턴은 : 몇회인지 , 말/초??(공격팀 수비팀) , 몇점인지, 공수교대 시점여부, 홈런을 때려맞으면 이게 1점짜리인지, 3점짜리인지 파악(출루주자)
    - 약간은 심판의 역할도 코드상으로 탑재되어야함 : 즉 야구 도메인 지식이 있으면 편안
- 예시2 : 주민관리시스템
  - POST시에는 입력받는건 : name, phoneNumber
  - 서버 내부에서 알아서 자동적으로 처리해야할 데이터 : age, phonmeModel, gender, createdAt, isAlive 등의 
  - GET시에만 돌려받아야할 데이터 : name, PrimaryKey, createdAt, age 
  • 결론 : 무지성으로 Entity, EntityDtoRequest, EntityDtoResponse

추가로 받아들일 스타일

https://velog.io/@p4rksh/Spring-Boot에서-깔끔하게-DTO-관리하기
https://velog.io/@ohzzi/Entity-DAO-DTO%EA%B0%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EB%A9%B0-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C





2) 어노테이션 NonNull

  • Nullness annotations : 널을 다루는 Annotations이 있는데
    • @NonNull : null을 허용하지 않을 경우
    • @Nullable : null을 허용할 경우
  • 위 두가지 어노테이션 모두 컴파일시점에 null의 가능성을 체크해주므로 라이브서버 성능에 영향이 없다.
    • 꼭쓰자 두번쓰자




3) 어노테이션 JsonIgnoreProperties

  • @JsonIgnoreProperties(ignoreUnknown = true) 을 왜쓸까?

3.1) 어노테이션 설명

  • json 데이터를 받아와서 엔티티(혹은 DTO 객체)로 맵핑할 때
    • 기본적으로 클래스에 선언되지 않은 프로퍼티가 json에 있으면 오류 발생하는데
      • 기본값은 (json 구성 = 클래스 구성) 완벽하게 동일해야한다
      • 그렇지 않으면 : org.codehaus.jackson.map.exc.UnrecognizedPropertyException 이 발생한다
  • 이 상황에서 예외 발생시키지 않고 클래스에 정의되지 않은 Json-Key를 무시하기 위해 사용하는 어노테이션임
  • @JsonIgnoreProperties(ignoreUnknown = true) 추가하면 Unknown 한 Json-Key들을 ignore한다!

3.2) 예시

  • 클래스의 맴버가 3개가 있는데
class MemberDto {
    Long id;
    int age;
    String name;
}
  • Json 데이터가 이렇게 4개로 하나가 추가로 더 들어오면
{
  "id":40,
  "age":27,
  "name":"Kim-Mac-Book",
  "status" : "angry"
}
  • 기존 : UnrecognizedPropertyException 발생후 종료
  • 변경 : 모르는 Json프로퍼티인 status는 버리고 프로그램은 정상동작




4) 어노테이션 JsonInclude NON_NULL

  • @JsonInclude(JsonInclude.Include.NON_NULL) 이 코드는 왜 쓰는걸까

4.1) 어노테이션 설명

  • 서버에서 응답 데이터를 리턴해줄때, ResponseDTO의 필드데이터 중 null이 있는 경우
  • Josn리턴데이터에서 value가 null인 항목을 생략하기 위해서 사용합니다
    • API 서버에서는 Response 대이터를 위한 class는 상황에 따라 필드를 전부 사용하지 않을수 있습니다
  • Josn 리턴데이터(Response) 에서 value가 null일때 @JsonInclude(JsonInclude.Include.NON_NULL) 을 추가해 주면 null인 데이터는 json결과에 나타나지 않습니다

4.2) 예시

  • 예시 : 의류도매 쇼핑몰의 Memeber 관리에서
  • 사용전
{
  "Name": "홍대남22",
  "shopMall": "홍대의류소매(주)",
  "phoneNumber": "010-1234-4567",
  "address": "서울시 마포구 홍익대로"
}


  • 사용후
{
  "Name": "홍대남22",
  "shopMall": "홍대의류소매(주)",
  "phoneNumber": "010-1234-4567",
  "address": "서울시 마포구 홍익대로"
}




단 한줄의 코드라도 모르고 쓰면 쥐약이고 알고쓰면 보약이다

  • 그래서 내 코드는 맨날 쥐와 벌레가 들끓는것인가?
profile
Sorbet is good...!

0개의 댓글