Skip to content

Driving Adapter

SilberBullet edited this page Feb 2, 2025 · 5 revisions

๐Ÿš€ Driving Adapter

๐Ÿซฐ Introduction

Hexagonal Architecture(ํ—ฅ์‚ฌ๊ณ ๋‚  ์•„ํ‚คํ…์ฒ˜)์˜ Driving Adapter๋Š” ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๋ฐ›์•„ Application Core๋กœ ์ „๋‹ฌํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€ ๊ณ„์ธต(์‚ฌ์šฉ์ž, ์‹œ์Šคํ…œ, ์ด๋ฒคํŠธ ์†Œ์Šค ๋“ฑ)๊ณผ Application์˜ ๋„๋ฉ”์ธ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์œ ์—ฐ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, Application์˜ UseCase๋ฅผ ํฌํŠธ๋กœ ํ• ๋‹น ๋ฐ›์•„ ์ž…์ถœ๋ ฅ์„ ์ •์˜ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋กœ ์ธํ•ด ์˜์กด๋„ ๋˜ํ•œ Application์œผ๋กœ ํ–ฅํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ backend-sample-hexagonal-simple-crud์˜ Driving Adapter๋Š” Rest API๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” Web Adapter๋ฅผ ๊ตฌํ˜„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

CQRS ํŒจํ„ด์„ ๋„์ž…ํ•˜์—ฌ Board(๊ฒŒ์‹œํŒ) ๋„๋ฉ”์ธ์˜ ์กฐํšŒ์™€ ๋ช…๋ น์„ ๊ฐ๊ฐ ๋ถ„๋ฆฌํ•˜์—ฌ ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

ํ•ญ๋ชฉ ์ž‘์—…์ž
QueryApi shin-jingyu
CommandApi silberbullet

๐Ÿ•ธ๏ธ Web Adapter

๐Ÿซ About REST Controller

  • HTTP ์š”์ฒญ ์ˆ˜์‹ : ํด๋ผ์ด์–ธํŠธ์˜ GET, POST, PATCH, DELETE ์š”์ฒญ ์ฒ˜๋ฆฌ
  • UseCase ํ˜ธ์ถœ: ์š”์ฒญ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์œผ๋กœ ์ „๋‹ฌ
API ์„ค๋ช… ๊ธฐ๋Šฅ
QueryApi ๋ฐ์ดํ„ฐ ์กฐํšŒ ๊ธฐ๋Šฅ์„ ๋‹ด๋‹นํ•˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ์˜ GET ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜
  • QueryApi ๊ตฌํ˜„
  • QueryApi ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ๋ฐ ๊ฒ€์ฆ
CommandApi ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ(์ƒ์„ฑ, ์ˆ˜์ •, ์‚ญ์ œ) ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ํด๋ผ์ด์–ธํŠธ์˜ POST, PATCH, DELETE ์š”์ฒญ์„ ์ฒ˜๋ฆฌ
  • CommandApi ๊ตฌํ˜„
  • CommandApi ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ๋ฐ ๊ฒ€์ฆ

๐Ÿ›  Mapper(MapStruct)์™€ DTO๋ฅผ ํ™œ์šฉํ•œ ์ „๋žต

๋ช…ํ™•ํ•œ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ ๊ตฌ์กฐํ™”๋ฅผ ์œ„ํ•ด Mapper์™€ DTO(Data Transfer Object) ๋ฅผ ํ™œ์šฉํ•˜์—ฌ Application ์˜์—ญ๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ์ „๋žต์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

โœจ Mapper์˜ ์—ญํ• 

  • Domain(๋„๋ฉ”์ธ)๊ณผ DTO ๊ฐ„ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ํ‘œํ˜„ ๊ณ„์ธต์„ ๋ถ„๋ฆฌ
  • ์„œ๋น„์Šค ๋ ˆ์ด์–ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๋Š” ์—ญํ• ์„ ์ตœ์†Œํ™”ํ•˜๊ณ , ๋‹จ์ˆœ ๋ณ€ํ™˜ ๋กœ์ง์„ ์ „๋‹ด

๐Ÿ— DTO๋ฅผ ํ™œ์šฉํ•œ ์ด์ 

  • ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ๊ฐ„ ์ผ๊ด€๋œ ๋ฐ์ดํ„ฐ ํฌ๋งท ์œ ์ง€
  • ๋„๋ฉ”์ธ ๋ชจ๋ธ ๋ณดํ˜ธ
  • REST API์˜ ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ–ฅ์ƒ

๐Ÿฆ– ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

โ—ํ•„์ˆ˜ Annotation

  • @WebMvcTest(BoardQueryApi::class)

    • BoardQueryApi๋ฅผ ๋นˆ์œผ๋กœ ๋กœ๋“œํ•˜๊ณ  MockMvc๋ฅผ ํ™œ์šฉํ•˜์—ฌ HTTP ์š”์ฒญ์„ ํ…Œ์ŠคํŠธํ•  ๋•Œ ์‚ฌ์šฉ
  • @MockitoBean

    • ํŠน์ • ๊ฐ์ฒด๋ฅผ Mockingํ•˜์—ฌ ํ…Œ์ŠคํŠธ ์ปจํ…์ŠคํŠธ์— ์ฃผ์ž…

๐Ÿ’š Kotest Style is FreeSpec

  • Kotest์—์„œ ์ œ๊ณตํ•˜๋Š” ํ…Œ์ŠคํŠธ ์Šคํƒ€์ผ ์ค‘ ํ•˜๋‚˜๋กœ, ๋ณด๋‹ค ์ž์œ ๋กœ์šด ๊ตฌ์กฐ์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Œ
  • ๊ณ„์ธต์  ๊ตฌ์กฐ ์—†์ด ๊ฐ„๊ฒฐํ•œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๊ฐ€๋Šฅ
@WebMvcTest(BoardQueryApi::class)
class BoardQueryApiTest(
    @MockitoBean private val boardReadUseCase: BoardReadUseCase,
    @MockitoBean private val boardReadByStatusesUseCase: BoardReadByStatusesUseCase,
    @MockitoBean private val boardDtoMapper: BoardDtoMapper,
    @Autowired private val mvc: MockMvc
) : FreeSpec({
  • beforeSpec {}

    • ์ „์ฒด ํ…Œ์ŠคํŠธ ์‹คํ–‰๋˜๊ธฐ ์ „์— ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋˜๋Š” ๋ธ”๋ก์œผ๋กœ ๊ณตํ†ต์ ์ธ ์„ค์ • ์ž‘์—…์„ ๊ตฌํ˜„
  • ๊ตฌ์กฐ

    • ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ๋Œ€๊ด„ํ˜ธ[]๋ฅผ ์ด์šฉํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ช… ๊ธฐ๋Šฅ ์ •์˜
    • ์„ค์ • ์ฝ”๋“œ(Mock ์„ค์ • ๋“ฑ)๋ฅผ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ฝ”๋“œ ์•„๋ž˜ ๋ฐฐ์น˜ํ•˜์—ฌ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ

๐Ÿ’ญ ํšŒ๊ณ 

@shin-jingyu

ํ—ฅ์‚ฌ๊ณ ๋‚  ์•„ํ‚คํ…์ฒ˜๋ฅผ ์ ์šฉํ•˜๋ฉด์„œ API์—์„œ ๋„๋ฉ”์ธ๊ณผ DTO๋ฅผ ๋งคํ•‘ํ•˜๋Š” ๊ณผ์ •์ด ์ฒ˜์Œ์—” ํ—ท๊ฐˆ๋ ธ์ง€๋งŒ, ๊ตฌํ˜„์„ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ ์  ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•ด์กŒ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ฒฝํ—˜์„ ํ†ตํ•ด Git๋„ ๋” ์ต์ˆ™ํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. PR๊ณผ ์ด์Šˆ ๊ด€๋ฆฌ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด๋ฉด์„œ ํ˜‘์—… ๊ณผ์ •์—์„œ ์–ด๋–ป๊ฒŒ ํ™œ์šฉ๋˜๋Š”์ง€ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๊ตฌ์กฐ์ ์ธ ๋ถ€๋ถ„์„ ๋” ๊นŠ์ด ๊ณ ๋ฏผํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ๊ฐ™์ด ์ž‘์—…ํ•œ ๊ฒฝ์šฐ๋‹˜ ๋•๋ถ„์— ๊ฐ€๋…์„ฑ์ด ์ข‹์€ ์ฝ”๋“œ๋กœ ๋‹ค๋“ฌ์„ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, HTTP ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜๋ฉด์„œ ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ๋งŽ์ด ๋Š˜์—ˆ๊ณ , ์ „๋ฐ˜์ ์œผ๋กœ ์ฝ”๋“œ์˜ ๊ตฌ์กฐ์™€ ํ…Œ์ŠคํŠธ ์„ค๊ณ„์— ๋Œ€ํ•ด ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๊ฒฝํ—˜์ด์—ˆ์Šต๋‹ˆ๋‹ค.