🌈 [Section3] 2. [ Spring MVC ] API 계측 2

ν˜„μ£ΌΒ·2022λ…„ 10μ›” 22일
0

bootcamp

λͺ©λ‘ 보기
42/71

πŸ“• 였늘 배운 λ‚΄μš©!

  • DTO 클래슀
  • μœ νš¨μ„± 검사

✏️ DTO (Data Transfer Object)

  • 데이터 전솑을 μœ„ν•œ μš©λ„μ˜ 객체
    ( μš”μ²­ 데이터와 응닡 λ°μ΄ν„°μ—μ„œ μ‚¬μš© )

➜ 주둜 ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ μ„œλ²„ μͺ½μœΌλ‘œ μ „μ†‘ν•˜λŠ” μš”μ²­ 데이터λ₯Ό 전달 받을 λ•Œ, μ„œλ²„μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈ μͺ½μœΌλ‘œ μ „μ†‘ν•˜λŠ” 응닡 데이터λ₯Ό μ „μ†‘ν•˜κΈ° μœ„ν•œ μš©λ„

βœ”οΈ Request Body
➜ μš”μ²­ 데이터 쀑 body에 ν•΄λ‹Ήλ˜λŠ” 데이터
( μ—¬κΈ°μ„œ λ§ν•˜λŠ” μš”μ²­ 데이터듀은 λͺ¨λ‘ Request Bodyλ₯Ό λ§ν•˜λŠ” 것 )

βœ” DTOκ°€ ν•„μš”ν•œ 이유

  • ν΄λΌμ΄μ–ΈνŠΈμ˜ Request Bodyλ₯Ό ν•˜λ‚˜μ˜ 객체둜 λͺ¨λ‘ 전달 받을 수 μžˆκΈ°λ•Œλ¬Έμ— μ½”λ“œ μžμ²΄κ°€ κ°„κ²°

  • Request Body의 데이터 μœ νš¨μ„±(Validation) 검증이 λ‹¨μˆœν•΄μ§

πŸ’‘ μ›λž˜ μ‹€μŠ΅ λ‚΄μš©μ—μ„œ Map으둜 μš”μ²­λ°μ΄ν„°λ₯Ό λ°›μ•˜μ—ˆλŠ”λ°
이 경우 데이터λ₯Ό ν•˜λ‚˜ν•˜λ‚˜ 받을 λ•Œ λ§ˆλ‹€ @RequestParam μ• λ„ˆν…Œμ΄μ…˜μ„ μ¨μ€˜μ•Όν•¨
➜ 데이터가 λ§Žμ•„μ§ˆ 수둝 뢈편
β €β €
λ”°λΌμ„œ DTO 클래슀λ₯Ό μ΄μš©ν•˜μ—¬ DTO ν΄λž˜μŠ€μ— μš”μ²­λ°μ΄ν„°λ₯Ό λ°›κ³ ,
κ·Έ DTO 클래슀λ₯Ό ResponseEntity 객체의 μƒμ„±μž νŒŒλΌλ―Έν„°λ‘œ λ„˜κ²¨μ£Όλ©΄ μ½”λ“œκ°€ 훨씬 간결해짐

βœ”οΈ ResponseEntity

  • HttpEntity의 ν™•μž₯ 클래슀둜써 HttpStatus μƒνƒœ μ½”λ“œλ₯Ό μΆ”κ°€ν•œ 전체 HTTP 응닡(μƒνƒœ μ½”λ“œ, 헀더 및 λ³Έλ¬Έ)을 ν‘œν˜„ν•˜λŠ” 클래슀
    [μ°Έκ³ ] https://itvillage.tistory.com/44

βœ”οΈ @RequestMapping
[μ°Έκ³ ] https://dzone.com/articles/using-the-spring-requestmapping-annotation

βœ” DTO의 μ‚¬μš© λͺ©μ 

  • HTTP μš”μ²­μ˜ 수λ₯Ό 쀄이기 μœ„ν•¨ (κ°€μž₯ μ€‘μš”ν•œ λͺ©μ )
    ➜ κ·Έ μš”μ²­μ— μ‚¬μš©λ˜λŠ” λΉ„μš©μ„ 쀄이기 μœ„ν•΄

βœ” DTO의 단점

  • DTO 클래슀λ₯Ό λ§Œλ“€ λ•Œ ν•΄λ‹Ή Contoller 클래슀 μ•ˆμ˜ DTO 클래슀 생성이 κ°€λŠ₯ν•œ ν•Έλ“€λŸ¬ λ©”μ„œλ“œμ˜ 개수만큼 μƒμ„±ν•˜κ²Œ λ˜λŠ”λ°,
    Controller ν΄λž˜μŠ€κ°€ λŠ˜μ–΄λ‚¨μ— 따라 μš°λ¦¬κ°€ μž‘μ„±ν•  DTO ν΄λž˜μŠ€λ„ λ‘λ°°λ‘œ λŠ˜μ–΄λ‚˜κ²Œ 됨 !!

➜ 이 뢀뢄은 κ³΅ν†΅λœ 멀버 λ³€μˆ˜μ˜ μΆ”μΆœ 및 λ‚΄λΆ€ 클래슀λ₯Ό μ‚¬μš©ν•˜μ—¬ μ–΄λŠμ •λ„ κ°œμ„ μ΄ κ°€λŠ₯ !


✏️ DTO 클래슀 μ μš©μ„ μœ„ν•œ μ½”λ“œ λ¦¬νŒ©ν† λ§ κ³Όμ •

  1. 각 ν•Έλ“€λŸ¬ λ©”μ„œλ“œμ˜ μš”μ²­ 데이터λ₯Ό 받을 DTO 클래슀 생성
    ( μ—¬κΈ°μ„œ DTO 클래슀 생성이 κ°€λŠ₯ν•œ ν•Έλ“€λŸ¬ λ©”μ„œλ“œλŠ” λ¦¬μ†ŒμŠ€μ˜ μΆ”κ°€κ°€ λ°œμƒν•  λ•Œλ§Œ κ°€λŠ₯
    Ex. POST , PATCH, PUT λ“±
  1. μš”μ²­ 데이터 ν•­λͺ©λ“€μ„ DTO 클래슀의 멀버 λ³€μˆ˜λ‘œ μΆ”κ°€ ν•˜κ³ , 각 멀버 λ³€μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” getter μΆ”κ°€

    But, setter λ©”μ„œλ“œλŠ” ν•„μš”μ— μ˜ν•œ 선택사항 !
    setter λ©”μ„œλ“œ 없이 getter λ©”μ„œλ“œλ§Œ μžˆμ–΄λ„ JSON ➜ 객체 의 λ³€ν™˜μ΄ κ°€λŠ₯ !
    [μ°Έκ³ ] https://stackoverflow.com/questions/70955984/why-requestbody-works-without-setters

  2. ν•Έλ“€λŸ¬ λ©”μ„œλ“œ μ•ˆμ˜ @RequestParam μͺ½ μ½”λ“œλ₯Ό DTO 객체둜 μˆ˜μ •

  3. Map 객체둜 μž‘μ„±λ˜μ–΄ μžˆλŠ” Response Body λ₯Ό DTO 클래슀 객체둜 λ³€κ²½

πŸ’‘ 포슀트맨으둜 잘 전달받고 μžˆλŠ”μ§€ 확인할 λ•Œ,
전달 λ°›λŠ” HTTP Request Bodyκ°€ JSON ν˜•μ‹μ΄μ–΄μ•Ό ν•˜κΈ° λ•Œλ¬Έμ— ν΄λΌμ΄μ–ΈνŠΈ μͺ½μ—μ„œ μ „λ‹¬ν•˜λŠ” Request Body μ—­μ‹œ JSON ν˜•μ‹μœΌλ‘œ μž…λ ₯ ν•΄μ•Ό ν•©

βœ”οΈ @RequestBody μ• λ„ˆν…Œμ΄μ…˜

  • JSON ν˜•μ‹μ˜ Request Body ➜ MemberPostDto 클래슀의 객체둜 λ³€ν™˜
    ( μ—¬κΈ°μ„œ Request Body - ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 받은 μš”μ²­ 데이터 )

  • JSON ν˜•μ‹μ΄ μ•„λ‹Œ λ‹€λ₯Έ ν˜•μ‹μ˜ 데이터λ₯Ό 전솑할 경우, μ—λŸ¬ 메세지λ₯Ό ν¬ν•¨ν•œ 응닡을 전달

    • @RequestBody둜 μš”μ²­μ„ λ°›λŠ”λ‹€λŠ” 것
      ➜ JSON ν˜•μ‹μœΌλ‘œ λ°›μ•„μ„œ λ°˜ν™˜
    • @RequestParam으둜 μš”μ²­μ„ λ°›λŠ”λ‹€λŠ” 것
      ➜ JSON ν˜•μ‹μ΄ μ•„λ‹Œ key value ν˜•μ‹μ„ λ°›μ•„μ„œ λ°˜ν™˜

βœ”οΈ @ResponseBody μ• λ„ˆν…Œμ΄μ…˜

  • DTO 클래슀의 객체 ➜ Response Body둜 λ³€ν™˜
    ( μ—¬κΈ°μ„œ Response Body - ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 보낼 응닡 데이터 )

πŸ’‘ Spring MVCμ—μ„œ ν•Έλ“€λŸ¬ λ©”μ„œλ“œμ— @ResponseBody μ• λ„ˆν…Œμ΄μ…˜μ΄ λΆ™κ±°λ‚˜, ν•Έλ“€λŸ¬ λ©”μ„œλ“œμ˜ 리턴값이 ResponseEntity일 경우 λ‚΄λΆ€μ μœΌλ‘œ HttpMessageConverterκ°€ λ™μž‘ν•˜κ²Œ λ˜μ–΄ 응닡 객체λ₯Ό JSON ν˜•μ‹μœΌλ‘œ λ°”κΏ”μ€Œ
β €
( 리턴값이 ResponseEntity일 경우 @ResponseBody μ• λ„ˆν…Œμ΄μ…˜ 뢙이면 μžλ™μœΌλ‘œ λ°”κΏ”μ€Œ )

βœ”οΈ JSON 직렬화(Serialization)

Java 객체 β†’ JSON ν˜•μ‹

βœ”οΈ JSON 역직렬화(Deserialization)

JSON ν˜•μ‹ β†’ Java 객체
β €
( ❗ μ—¬κΈ°μ„œ Java κ°μ²΄λž€ DTO 같은 클래슀λ₯Ό λ§ν•˜λŠ” 것 ! )


✏️ μœ νš¨μ„±(Validation) 검증

  • 일반적으둜 ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μš”μ²­ 데이터가 전달될 λ•Œ, μš°λ¦¬ν•œν…Œ λ„˜μ–΄μ˜€λŠ” κ·Έ λ°μ΄ν„°λŠ” 1차적으둜 μœ νš¨μ„± 검증이 μ§„ν–‰λœ λ°μ΄ν„°μž„
    But, 이 값을 μ‘°μž‘ν•  수 μžˆμ–΄ λ°˜λ“œμ‹œ μœ νš¨ν•œ 값이라 λ³Ό 수 μ—†κΈ° λ•Œλ¬Έμ—
    μ„œλ²„ μͺ½μ—μ„œ λ°˜λ“œμ‹œ ν•œλ²ˆ 더 μœ νš¨μ„± 검사λ₯Ό 해야함

  • μ„œλ²„ μͺ½μ—μ„œ μœ νš¨ν•œ 데이터λ₯Ό 전달 λ°›κΈ° μœ„ν•΄ 데이터λ₯Ό κ²€μ¦ν•˜λŠ” 것

πŸ’‘ ν•Έλ“€λŸ¬ λ©”μ„œλ“œ 내에 μœ νš¨μ„± 검증을 ν•˜κ²Œ 되면, μš”μ²­ λ°μ΄ν„°μ˜ 개수만큼 λ©”μ„œλ“œ 내에 검증 둜직이 λ„˜μ³λ‚˜κ²Œ 됨
➜ μ½”λ“œ λ³΅μž‘λ„ 높아짐
β €
ν•Έλ“€λŸ¬ λ©”μ„œλ“œλŠ” μš”μ²­μ„ μ „λ‹¬λ°›λŠ” 것이 μ£Ό λͺ©μ μ΄λΌ μ΅œλŒ€ν•œ κ°„κ²°ν•˜κ²Œ μž‘μ„±ν•΄μ•Όν•˜κΈ°μ—
β €
DTO ν΄λž˜μŠ€μ™€ μœ νš¨μ„± 검증 μ• λ„ˆν…Œμ΄μ…˜μ„ μ΄μš©ν•˜μ—¬
μœ νš¨μ„± 검증 λ‘œμ§μ„ DTO 클래슀둜 λΉΌλ‚΄μ–΄ ν•Έλ“€λŸ¬ λ©”μ„œλ“œμ˜ 간결함 μœ μ§€ κ°€λŠ₯
β €
πŸ’‘ DTO ν΄λž˜μŠ€μ—μ„œ μœ νš¨μ„± 검증 μ‹œ,
ν΄λΌμ΄μ–ΈνŠΈμ˜ μš”μ²­ 데이터에 μœ νš¨ν•˜μ§€ μ•Šμ€ 데이터가 μžˆλ‹€λ©΄ μœ νš¨μ„± 검증에 μ‹€νŒ¨
➜ ν΄λΌμ΄μ–ΈνŠΈμ˜ μš”μ²­μ΄ 거뢀됨

βœ” μœ νš¨μ„±(validation) 검증 μ• λ„ˆν…Œμ΄μ…˜μ˜ μ‚¬μš©

  • Spring Boot 2.3버전뢀터 javax.validation이 spring-boot-starter-web에 ν¬ν•¨λ˜μ–΄ μžˆμ§€ μ•ŠκΈ° λ•Œλ¬Έμ—,
    build.gradle의 dependencies ν•­λͺ©μ— λ”°λ‘œ μ•„λž˜μ˜ μ˜μ‘΄μ„±μ„ μΆ”κ°€ν•΄μ€˜μ•Ό μ•„λž˜μ˜ μ• λ„ˆν…Œμ΄μ…˜λ“€μ„ μ‚¬μš© κ°€λŠ₯함 ⬇️
implementation 'org.springframework.boot:spring-boot-starter-validation'

βœ”οΈ java.validation μ• λ„ˆν…Œμ΄μ…˜

  • @NotNull - Null λΆˆκ°€
  • @Null - Null만 μž…λ ₯ κ°€λŠ₯
  • @NotEmpty - Null, 빈 λ¬Έμžμ—΄ λΆˆκ°€
  • @NotBlank - Null, 빈 λ¬Έμžμ—΄, 슀페이슀만 μžˆλŠ” λ¬Έμžμ—΄ λΆˆκ°€ ( String νƒ€μž…μ—λ§Œ μ‚¬μš© )
  • @Size(min =,max =) - λ¬Έμžμ—΄, λ°°μ—΄λ“±μ˜ 크기 지정
  • @Pattern(regex =) - μ •κ·œμ‹μ„ λ§Œμ‘±ν•˜λŠ”κ°€
  • @Max(숫자) - 받을 수 μžˆλŠ” μ΅œλŒ€κ°’ 지정
  • @Min(숫자) - 받을 수 μžˆλŠ” μ΅œμ†Ÿκ°’ 지정
  • @Future - ν˜„μž¬ 보닀 미래의 μˆœκ°„(λ‚ μ§œ, μ‹œκ°„)만 받도둝 지정
  • @Past - ν˜„μž¬ 보닀 과거의 μˆœκ°„(λ‚ μ§œ, μ‹œκ°„)만 받도둝 지정
  • @Positive - μ–‘μˆ˜λ§Œ κ°€λŠ₯
  • @PositiveOrZero - μ–‘μˆ˜μ™€ 0만 κ°€λŠ₯
  • @Negative - 음수만 κ°€λŠ₯
  • @NegativeOrZero - μŒμˆ˜μ™€ 0만 κ°€λŠ₯
  • @Email - 이메일 ν˜•μ‹λ§Œ κ°€λŠ₯
    [μ°Έκ³ ] https://en.wikipedia.org/wiki/Email_address
  • @Digits(integer =, fraction =) - λŒ€μƒ μˆ˜κ°€ μ§€μ •λœ μ •μˆ˜μ™€ μ†Œμˆ˜ 자리 수 보닀 μž‘μ€κ°€?
  • @DecimalMax(value =) - μ§€μ •λœ κ°’(μ‹€μˆ˜) μ΄ν•˜μΈκ°€?
  • @DecimalMin(value =) - μ§€μ •λœ κ°’(μ‹€μˆ˜) 이상인가?
  • @AssertFalse - 값을 false만 받도둝 지정
  • @AssertTrue - 값을 true만 받도둝 지정
    β €β €
    ( μœ„μ˜ μ• λ„ˆν…Œμ΄μ…˜λ“€μ„ λͺ¨λ‘ Jakarta Bean Validationμ΄λΌλŠ” μœ νš¨μ„± 검증을 μœ„ν•œ ν‘œμ€€ μŠ€νŽ™μ—μ„œ μ§€μ›ν•˜λŠ” λ‚΄μž₯ μ• λ„ˆν…Œμ΄μ…˜λ“€μž„ )

βœ”οΈ 각 μ• λ„ˆν…Œμ΄μ…˜μ—λŠ” κ³΅ν†΅μ μœΌλ‘œ message 속성 적용 κ°€λŠ₯
( message - μœ νš¨μ„± 검사에 μ‹€νŒ¨ν•  경우, λ Œλ”λ§ λ˜λŠ” λ©”μ‹œμ§€ )
Ex. @NotNull (message = "ν•΄λ‹Ή 값이 Nullμž…λ‹ˆλ‹€.")

βœ”οΈ μœ νš¨μ„± 검증 μ• λ„ˆν…Œμ΄μ…˜μ΄ μΆ”κ°€λœ DTO ν΄λž˜μŠ€μ—μ„œ μœ νš¨μ„± 검증 둜직이 μ‹€ν–‰λ˜κ²Œ ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν•΄λ‹Ή Contoller 클래슀의 ν•Έλ“€λŸ¬ λ©”μ„œλ“œ νŒŒλΌλ―Έν„°μ— @Valid μ• λ„ˆν…Œμ΄μ…˜μ„ 좔가해야함

βœ”οΈ ν•Έλ“€λŸ¬ λ©”μ„œλ“œμ˜ URI pathμ—μ„œ μ‚¬μš©λ˜λŠ” Id의 μœ νš¨μ„± μ œν•œμ„ λ‘λŠ” @PathVariable μ• λ„ˆν…Œμ΄μ…˜μ΄ 뢙을 경우, 클래슀 λ ˆλ²¨μ— @Validated μ• λ„ˆν…Œμ΄μ…˜μ„ λ°˜λ“œμ‹œ 뢙여주어야함

[μ°Έκ³ ] https://immose93.tistory.com/139
[μ°Έκ³ ] https://hyeran-story.tistory.com/81

βœ”οΈ Jakarta Bean Validation

  • 라이브러리처럼 μ‚¬μš©ν•  수 μžˆλŠ” APIκ°€ μ•„λ‹Œ μŠ€νŽ™(사양, Specification) 자체
  • 이 μŠ€νŽ™μ„ κ΅¬ν˜„ν•œ κ΅¬ν˜„μ²΄κ°€ Hibernate Validator
    ➜ Java Bean μŠ€νŽ™μ„ μ€€μˆ˜ν•˜λŠ” Java 클래슀라면 Jakarta Bean Validation의 μ• λ„ˆν…Œμ΄μ…˜μ„ μ‚¬μš©ν•΄μ„œ μœ νš¨μ„± 검증을 ν•  수 μžˆλ‹€ !

βœ” μ •κ·œν‘œν˜„μ‹ (Reqular Experssion)

[μ •κ·œν‘œν˜„μ‹ μ°Έκ³  링크]
https://www.w3schools.com/java/java_regex.asp
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions
https://learn.microsoft.com/ko-kr/dotnet/standard/base-types/best-practices
https://moonong.tistory.com/31
https://jamesdreaming.tistory.com/201
https://highcode.tistory.com/6

Ex. β€œ^\\S+(\\s?\\S+)*$” ➜ λ¬Έμžμ—΄λ“€ 사이에 곡백 0~1개만 ν—ˆμš©


✏️ Custom Validator

  • λ‚΄ λͺ©μ μ— λ§žλŠ” μ• λ„ˆν…Œμ΄μ…˜μ΄ Jakarta Bean Validation에 λ‚΄μž₯된(Built-in) μ• λ„ˆν…Œμ΄μ…˜ 쀑에 없을 수 있음
    ➜ 직접 λ§Œλ“€μ–΄μ„œ μœ νš¨μ„± 검증에 적용 κ°€λŠ₯ !

πŸ’‘ μ •κ·œ ν‘œν˜„μ‹(Regular Expression)은 μ„±λŠ₯적인 λ©΄μ—μ„œ λ•Œλ‘œλŠ” λΉ„μ‹Ό λΉ„μš©μ„ μΉ˜λ€„μ•Ό 될 κ°€λŠ₯성이 있음
➜ λͺ¨λ“  λ‘œμ§μ„ μ •κ·œν‘œν˜„μ‹ μœ„μ£Όλ‘œ μž‘μ„±ν•˜λŠ” 것은 쒋은 개발 방식이 μ•„λ‹ˆκΈ°μ—
상황에 따라 Custom Validator μ‚¬μš©ν•˜κΈ°

Custom Validatorλ₯Ό κ΅¬ν˜„ν•˜κΈ° μœ„ν•œ 절차

  1. Custom Annotation을 μ •μ˜

  2. μ •μ˜ν•œ Custom Annotation에 바인딩 λ˜λŠ” Custom Validator κ΅¬ν˜„

  3. μœ νš¨μ„± 검증이 ν•„μš”ν•œ DTO 클래슀의 멀버 λ³€μˆ˜μ— Custom Annotation μΆ”κ°€


✏️ DTO μΆ”κ°€ μ‹€μŠ΅

  • projects 폴더 Section2-Week1 μ°Έκ³  !

🌈 λŠλ‚€μ 

μ–΄μ œ 였늘 직접 해보고 포슀트맨으둜 ν™•μΈν•΄λ³΄λŠ”κ²Œ μž¬λ°Œμ—ˆλ‹€ !!γ…Žγ…Ž

0개의 λŒ“κΈ€