๐ŸŒˆ [Section3] 3. [ Spring MVC ] ์„œ๋น„์Šค ๊ณ„์ธต

ํ˜„์ฃผยท2022๋…„ 10์›” 24์ผ
0

bootcamp

๋ชฉ๋ก ๋ณด๊ธฐ
43/71

๐Ÿ“• ์˜ค๋Š˜ ๋ฐฐ์šด ๋‚ด์šฉ!

  • Cotroller ํด๋ž˜์Šค์™€ Service ํด๋ž˜์Šค์˜ ์—ฐ๋™ with DI
  • MapStruct๋ฅผ ์ด์šฉํ•œ Mapper

โœ๏ธ ์„œ๋น„์Šค ๊ณ„์ธต

  • API ๊ณ„์ธต์—์„œ ์ „๋‹ฌ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‹ค์งˆ์ ์ธ ๋น„์ฆˆ๋‹ˆ์Šค ์š”๊ตฌ์‚ฌํ•ญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณ„์ธต

  • Spring์˜ DI(์˜์กด์„ฑ ์ฃผ์ž…)๋ฅผ ์ด์šฉํ•˜์—ฌ API ๊ณ„์ธต๊ณผ ๋น„์ฆˆ๋‹ˆ์Šค(์„œ๋น„์Šค) ๊ณ„์ธต์„ ์—ฐ๋™ํ•˜๊ณ ,
    API ๊ณ„์ธต์—์„œ ์ „๋‹ฌ๋ฐ›์€ DTO ๊ฐ์ฒด๋ฅผ ๋น„์ฆˆ๋‹ˆ์Šค(์„œ๋น„์Šค) ๊ณ„์ธต์˜ ๋„๋ฉ”์ธ Entity ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์ „ํ™˜

โœ”๏ธ API ๊ณ„์ธต๊ณผ ์„œ๋น„์Šค ๊ณ„์ธต์„ ์—ฐ๋™ํ•œ๋‹ค
โžœ API ๊ณ„์ธต์—์„œ ๊ตฌํ˜„ํ•œ Controller ํด๋ž˜์Šค๊ฐ€ ์„œ๋น„์Šค ๊ณ„์ธต์˜ Service ํด๋ž˜์Šค์™€ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ํ†ตํ•ด ์ƒํ˜ธ ์ž‘์šฉํ•œ๋‹ค

โœ”๏ธ ์„œ๋น„์Šค ๊ณ„์ธต์€ ๋Œ€๋ถ€๋ถ„ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Œ
๋„๋ฉ”์ธ ๋ชจ๋ธ์€ ๋นˆ์•ฝํ•œ ๋„๋ฉ”์ธ ๋ชจ๋ธ(anemic domain model) / ํ’๋ถ€ํ•œ ๋„๋ฉ”์ธ ๋ชจ๋ธ(rich domain model)๋กœ ๊ตฌ๋ถ„๋˜๊ณ ,
์ด๋Š” DDD(๋„๋ฉ”์ธ ์ฃผ๋„ ์„ค๊ณ„, Domain Driven Design)์™€ ๊ด€๋ จ์ด ๊นŠ์Œ


DTO ํด๋ž˜์Šค์™€ ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค์˜ ์—ญํ•  ๋ถ„๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

โœ”๏ธ ๊ณ„์ธต๋ณ„ ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ

  • ๊ธฐ๋Šฅ ๋ณ„๋กœ ์„œ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ณ„์ธต์ด ๋‹ค๋ฆ„
    โžœ OOP์˜ ๋‹จ์ผ ์ฑ…์ž„์˜ ์›์น™ (SRP)์— ๋”ฐ๋ผ ๋” ์ข‹์€ OOP ํ•˜๊ธฐ ์œ„ํ•ด

    ๐Ÿ’ก DTO ํด๋ž˜์Šค

    • API ๊ณ„์ธต์—์„œ ํด๋ผ์ด์–ธํŠธ์˜ Request Body๋ฅผ ์ „๋‹ฌ ๋ฐ›๊ณ  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋˜๋Œ๋ ค ์ค„ ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ์—ญํ• 
    • API ๊ณ„์ธต์—์„œ ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ ๋ฐ›๊ณ , ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜๋Š”๊ฒƒ์ด ์ฃผ ๋ชฉ์ 

    ๐Ÿ’ก Entity ํด๋ž˜์Šค

    • ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ๋ฐ์ดํ„ฐ ์•ก์„ธ์Šค ๊ณ„์ธต๊ณผ ์—ฐ๋™ํ•˜๋ฉด์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ์—ญํ• ์„ ํ•˜๋Š” ํด๋ž˜์Šค
    • API ๊ณ„์ธต์—์„œ ์ „๋‹ฌ ๋ฐ›์€ ์š”์ฒญ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ ๋ฐ›๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•œ ํ›„์—๋Š” ๊ฒฐ๊ณผ ๊ฐ’์„ ๋‹ค์‹œ API ๊ณ„์ธต์œผ๋กœ ๋ฆฌํ„ดํ•ด์ฃผ๋Š” ์—ญํ• 
      โ €
      ( DTO ํด๋ž˜์Šค์™€ ๋น„์ฆˆ๋‹ˆ์Šค ํด๋ž˜์Šค ํ•ฉ์นœ ์—ญํ•  )

โœ”๏ธ ์ฝ”๋“œ ๊ตฌ์„ฑ์˜ ๋‹จ์ˆœํ™”

  • DTO ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์• ๋„ˆํ…Œ์ด์…˜์ด Entity ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉ์ด ๋œ๋‹ค๋ฉด JPA์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์• ๋„ˆํ…Œ์ด์…˜๊ณผ ๋’ค์„ž์ธ ์ƒํƒœ๊ฐ€ ๋˜์–ด ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์ƒ๋‹นํžˆ ์–ด๋ ค์šด ์ฝ”๋“œ๊ฐ€ ๋  ๊ฒƒ

โœ”๏ธ REST API ์ŠคํŽ™์˜ ๋…๋ฆฝ์„ฑ ํ™•๋ณด

  • Entity ํด๋ž˜์Šค๋ฅผ ์‘๋‹ต์œผ๋กœ ์ „๋‹ฌํ•˜๊ฒŒ ๋˜๋ฉด ์›์น˜์•Š๋Š” ๋ฐ์ดํ„ฐ๊นŒ์ง€ ์ „๋‹ฌ๋  ์ˆ˜ ์žˆ์Œ Ex. password
    โžœ DTO ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‘๋‹ต์œผ๋กœ ์ „๋‹ฌํ•ด ์›ํ•˜๋Š” ์ •๋ณด๋งŒ ์ œ๊ณต ๊ฐ€๋Šฅ

โœ๏ธ Mapper

  • DTO ํด๋ž˜์Šค์ฒ˜๋Ÿผ Java Bean ๊ทœ์•ฝ์„ ์ง€ํ‚ค๋Š” ๊ฐ์ฒด๋“ค ๊ฐ„์˜ ๋ณ€ํ™˜ ๊ธฐ๋Šฅ์„ ์ œ๊ณต
    ( ์—ญํ•  ๊ตฌ๋ถ„์„ ์œ„ํ•ด DTO โžœ Entity / Entity โžœ DTO ์˜ ๋ณ€ํ™˜์„ ์ด๋ฃจ์–ด์คŒ )

โœ๏ธ MapStruct

  • ๋งคํผ(Mapper) ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ฃผ๋Š” ์ฝ”๋“œ ์ž๋™ ์ƒ์„ฑ๊ธฐ

    โ— MapStruct ์‚ฌ์šฉ์„ ์œ„ํ•ด์„œ๋Š” ์•„๋ž˜ ์˜์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ build.gradle ํŒŒ์ผ์˜ dependencies ์— ์ถ”๊ฐ€ํ•ด์•ผํ•จ

    implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
  • ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ •์˜ํ•œ Mapper ์ธํ„ฐํŽ˜์ด์Šค์—๋Š” @Mapper ์• ๋„ˆํ…Œ์ด์…˜์„ ๋ถ™์—ฌ MapStruct์˜ ๋งคํผ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ •์˜๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผํ•˜๊ณ ,

  • @Mapper ์• ๋„ˆํ…Œ์ด์…˜์˜ ์• ํŠธ๋ฆฌ๋ทฐํŠธ๋กœ componentModel = "spring"์„ ์ง€์ •ํ•ด์ฃผ์–ด Spring Bean์œผ๋กœ ๋“ฑ๋ก๋  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผํ•จ

  • ์ด MapStruct๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€ Mapper ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค๋Š” ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์–ด build > classes ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด์— Mapper ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์œ„์น˜ํ•œ ํŒจํ‚ค์ง€ ์•ˆ์— MapperImpl์ด๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ƒ์„ฑ๋จ


๐Ÿ˜œ ๋น„์ฆˆ๋‹ˆ์Šค ๊ณ„์ธต๊ณผ API ๊ณ„์ธต ์—ฐ๋™ ์‹ค์Šต

  • projects ํด๋”์˜ be-template-service-layer ์ฐธ๊ณ !

  • ์‹ค์Šต ๊ณผ์ œ๋Š” git ํด๋”์˜ be-homework-mpaaer ์ฐธ๊ณ !

์ด์ „ ์‹ค์Šต์—์„œ DTO ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•ด ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ฐ›์•„ ๋‹ค์‹œ ์š”์ฒญ์„ ์ „๋‹ฌํ•˜๋„๋ก Controller์— DTO ํด๋ž˜์Šค๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ์‚ฌ์šฉํ–ˆ์—ˆ๋Š”๋ฐ,

์ด๋Š” OOP์˜ SRP(๋‹จ์ผ ์ฑ…์ž„ ์›์น™, Single Responsibility Principle)์— ๋”ฐ๋ผ,
๊ฐ ํด๋ž˜์Šค๋Š” ํ•˜๋‚˜์˜ ์—ญํ• ๋งŒ ํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹์Œ

์ด์ „ ์‹ค์Šต์—์„œ ํ–ˆ๋˜ ๋ฐฉ๋ฒ•์€ DTO ํด๋ž˜์Šค๊ฐ€ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ๋„ ๋ฐ›๊ณ , ์ด๋ฅผ Entity ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ ์‹œ์ผœ์ฃผ๋Š” ์—ญํ• ๊นŒ์ง€ ํ•จ
( API ๊ณ„์ธต๊ณผ Service ๊ณ„์ธต ๊ตฌ๋ถ„ ๋ถˆ๊ฐ€ )

๋”ฐ๋ผ์„œ, ์ด ๋‘ ๊ณ„์ธต์„ ๋ถ„๋ฆฌ์‹œํ‚ค๊ธฐ ์œ„ํ•ด

โ— Service ํด๋ž˜์Šค์™€ Entity ํด๋ž˜์Šค๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“  ํ›„, MapStruct๋ฅผ ์ด์šฉํ•œ Mapper ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DTO - Entity ๊ฐ„์˜ ๋ณ€๊ฒฝ์„ ํ•ด์ค„ ๊ฒƒ์ž„

๊ทธ๋ฆฌ๊ณ  Controller ๊ฐ์ฒด์— ์ƒ์„ฑ์ž์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Service ๊ฐ์ฒด, Entity ๊ฐ์ฒด ๋ชจ๋‘ ์˜์กด์„ฑ ์ฃผ์ž…(DI)์„ ํ†ตํ•ด
๊ฐ ํ•ธ๋“ค๋Ÿฌ ๋ฉ”์„œ๋“œ์˜ Body์— DTO ํด๋ž˜์Šค๋ฅผ Mapper๋กœ ์ด์šฉํ•ด Entity ๊ฐ์ฒด๋กœ ๋ฐ”๊พธ๊ณ , ์ด๋ฅผ Service ํด๋ž˜์Šค์™€ ์—ฐ๋™ํ•œ ํ›„,
๋ฆฌํ„ด๊ฐ’์œผ๋กœ ๊ทธ ๋ฐ”๊ฟ” ์—ฐ๋™ํ•œ Entity ๊ฐ์ฒด์™€ ์ƒํƒœ์ฝ”๋“œ๋ฅผ ๊ฐ™์ด ๋„ฃ์–ด
์ฃผ๋ฉด ๋จ

โœ”๏ธ Lombok ๊ธฐ๋Šฅ๋“ค (์• ๋„ˆํ…Œ์ด์…˜)
[์ฐธ๊ณ ] https://projectlombok.org/features/


โœ”๏ธ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ์‹œ ์ฃผ์˜ํ•  ์ 

Spring Boot initialize๋กœ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ์‹œ, @SpringBootAplication ์• ๋„ˆํ…Œ์ด์…˜์ด ๋ถ™์€ Application.class ๊ฐ€ ์ƒ์„ฑ๋จ

์ด @SpringBootAplication ์• ๋„ˆํ…Œ์ด์…˜์ด ๋ถ™์œผ๋ฉด, ๊ทธ ํด๋ž˜์Šค๋ถ€ํ„ฐ ๊ทธ ํ•˜์œ„๋ฅผ ๋ชจ๋‘ ๊ฒ€์‚ฌํ•˜๋ฉฐ @Component๋“ค ์ฐพ์•„์„œ ๊ฒ€์‚ฌํ•จ

๊ทธ๋ž˜์„œ Application.class ๋Š” ์ตœ์ƒ์œ„ ํด๋”(ํ”„๋กœ์ ํŠธ ์ด๋ฆ„ ํด๋”) ๋ฐ”๋กœ ๋ฐ‘์—๋งŒ ๋“ค์–ด๊ฐ€๊ณ  ์–ด๋– ํ•œ ํด๋”์—๋„ ๋“ค์–ด๊ฐ€๋ฉด ์•ˆ๋จ !

โžœ ํ•œ ํด๋”์— ๋“ค์–ด๊ฐ€๊ฒŒ ๋˜๋ฉด ๊ทธ ํด๋”์˜ ํ•˜์œ„ ํŒŒ์ผ๋“ค๋งŒ ๊ฒ€์‚ฌํ•˜๊ฒŒ ๋˜์–ด์„œ ๋ชจ๋“  ํด๋ž˜์Šค๋“ค์ด Application.class ๋กœ๋ถ€ํ„ฐ ํ•˜์œ„๋กœ ์ญ‰ ์‹œ์ž‘๋˜์–ด์•ผ ํ•จ


๐ŸŒˆ ๋Š๋‚€์ 

์–ด์ œ๋ณด๋‹จ ๋ญ”๊ฐ€ ์–‘์ด ๋งŽ์•„์ ธ์„œ ๊ตฌ์กฐ๊ฐ€ ํ•œ๋ˆˆ์— ์žกํžˆ์ง€ ์•Š์•˜์ง€๋งŒ ๊ทธ๋ž˜๋„ ํ•˜๋ฉด์„œ ์ ์  ๊นจ๋‹ฌ์•„๊ฐ€๊ณ  ์ด๊ฒŒ ์™œ ์ด๋ ‡๊ฒŒ ์ด์–ด์ ธ ์žˆ๋Š”์ง€ ์ดํ•ด๊ฐ€ ๋˜๋Š” ๊ฒŒ ์žฌ๋ฐŒ๋‹ค !
ํ™•์‹คํžˆ ๊ฐœ๋…๋งŒ ๊ณต๋ถ€ํ•˜๋Š” ๊ฒƒ ๋ณด๋‹ค ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์จ๋ณด๋ฉด์„œ ํ•˜๋‹ˆ๊นŒ ๊ธฐ์–ต๋„ ์ดํ•ด๋„ ๋” ์ž˜ ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค ใ…Žใ…Ž

0๊ฐœ์˜ ๋Œ“๊ธ€