πŸ“ 개발

ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ DIPλŠ” 어디에 μ“°μΌκΉŒ? μžλ™ν™” 도ꡬλ₯Ό μž¬μ„€κ³„ν•˜λ©° 얻은 μΈμ‚¬μ΄νŠΈ


직μž₯λ™λ£Œμ™€ ν•¨κ»˜ ν”„λ‘ νŠΈμ—”λ“œ 개발 생산성에 λŒ€ν•΄ ν† λ‘ ν•˜λ‹€κ°€, λ°˜λ³΅λ˜λŠ” λ‹¨μˆœ μž‘μ—…μ„ 쀄이기 μœ„ν•œ μžλ™ν™” ν”„λ‘œμ νŠΈλ₯Ό μ‹œμž‘ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. ν˜„μž¬λŠ” μ˜€ν”ˆμ†ŒμŠ€ 라이브러리λ₯Ό μ»€μŠ€ν…€ν•˜κ±°λ‚˜ 직접 μ œμž‘ν•œ 도ꡬ듀을 npm에 λ°°ν¬ν•˜μ—¬ μ‹€μ œ νŒ€ λ‚΄ ν”„λ‘œμ νŠΈμ— μ μš©ν•΄ μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

  • msw-auto-mock: OpenAPI μŠ€νŽ™ 기반의 MSW ν•Έλ“€λŸ¬ μžλ™ 생성 λ„κ΅¬μž…λ‹ˆλ‹€. κΈ°μ‘΄ 라이브러리λ₯Ό ν¬ν¬ν•˜μ—¬, λ³΅μž‘ν•œ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ— λŒ€μ‘ν•  수 μžˆλ„λ‘ μ‹œλ‚˜λ¦¬μ˜€λ³„ μ»€μŠ€ν…€ κΈ°λŠ₯을 ν™•μž₯ν–ˆμŠ΅λ‹ˆλ‹€.
  • e2e-autogen: ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€κ°€ λ‹΄κΈ΄ μŠ€ν”„λ ˆλ“œ μ‹œνŠΈ 데이터λ₯Ό Playwright ν…ŒμŠ€νŠΈ μŠ€ν…(Stub)μ½”λ“œλ‘œ λ³€ν™˜ν•΄ μ£ΌλŠ” λ„κ΅¬μž…λ‹ˆλ‹€.
  • api-recorder: μ‹€μ œ λ„€νŠΈμ›Œν¬ API ν˜ΈμΆœμ„ λ…Ήν™”ν•˜μ—¬ JSON λ°μ΄ν„°λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€. μ΄λŠ” μ•žμ„  두 도ꡬ와 ν†΅ν•©λ˜μ–΄, μ‹€μ œ 데이터λ₯Ό 기반으둜 ν•œ μ •κ΅ν•œ MSW, Playwright λͺ©μ—…을 μƒμ„±ν•˜λŠ” 데이터λ₯Ό λ§Œλ“œλŠ” 핡심 역할을 ν•©λ‹ˆλ‹€.

ν•˜μ§€λ§Œ 이 도ꡬ듀을 ν™œμš©ν•΄ Playwright E2E μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ‹€ λ³΄λ‹ˆ λͺ‡ κ°€μ§€ μ‹€μ§ˆμ μΈ λΆˆνŽΈν•¨μ„ λ°œκ²¬ν•˜κ²Œ λ˜μ—ˆκ³ , 이λ₯Ό κ°œμ„ ν•˜λŠ” κ³Όμ •μ—μ„œ κΈ°μ‘΄ μ„€κ³„μ˜ ꡬ쑰적 결함과 μ˜μ‘΄μ„± 문제둜 μΈν•œ ν™•μž₯μ„±μ˜ ν•œκ³„λ₯Ό λŠκΌˆμŠ΅λ‹ˆλ‹€. 이번 κΈ€μ—μ„œλŠ” κΈ°μ‘΄ λ„κ΅¬μ˜ λΆˆνŽΈν•¨μ„ κ°œμ„ ν•¨κ³Ό λ™μ‹œμ—, 더 μœ μ—°ν•œ μ•„ν‚€ν…μ²˜λ‘œ μž¬μ„€κ³„ν•˜λ©° κ³ λ―Όν–ˆλ˜ 과정듀을 이야기해보렀 ν•©λ‹ˆλ‹€.

μ–΄λ–€ λΆˆνŽΈν•¨μ΄ μžˆμ—ˆμ„κΉŒ?

api-recorder: 보쑰 λ„κ΅¬λ‘œ μ“°κΈ°μ—λŠ” κ°œμž… λΉ„μš©μ΄ ν½λ‹ˆλ‹€

api-recorder λ™μž‘ ν™”λ©΄

κ°œλ°œν•  λ•ŒλŠ” 보톡 개발자 도ꡬλ₯Ό ν•­μ‹œ 열어두고 μž‘μ—…ν•©λ‹ˆλ‹€. api-recorder둜 λ„€νŠΈμ›Œν¬ 둜그λ₯Ό μˆ˜μ§‘ν•  λ•Œλ„ λ§ˆμ°¬κ°€μ§€μ΄κ³ , 여기에 TanStack Query DevtoolsκΉŒμ§€ ν•¨κ»˜ μ‚¬μš©ν•˜λŠ” κ²½μš°λ„ λ§ŽμŠ΅λ‹ˆλ‹€.

이 μƒνƒœμ—μ„œ λ„€νŠΈμ›Œν¬ λ…Ήν™”λ₯Ό μœ„ν•΄ api-recorder νŒ¨λ„κΉŒμ§€ μΆ”κ°€λ‘œ μ—΄κ²Œ 되면, ν™”λ©΄μ—μ„œ κ°€λ €μ§€λŠ” μ˜μ—­μ΄ λ§Žμ•„μ Έ μž‘μ—… 흐름이 λŠκΈ°λŠ” λŠλ‚Œμ„ λ°›μ•˜μŠ΅λ‹ˆλ‹€. λ¬Όλ‘  νŒ¨λ„μ„ μ΅œμ†Œν™”ν•  μˆ˜λŠ” μžˆμ§€λ§Œ, λ…Ήν™” κ²°κ³Όλ₯Ό 쀑간쀑간 ν™•μΈν•˜λ €λ©΄ λ‹€μ‹œ μ—΄μ–΄μ•Ό ν–ˆκ³ , 이 과정이 λ°˜λ³΅λ˜λ©΄μ„œ μ€κ·Όν•œ ν”Όλ‘œλ„κ°€ μŒ“μ˜€μŠ΅λ‹ˆλ‹€.

μ‚¬μ†Œν•œ λΆˆνŽΈν•¨μ²˜λŸΌ 보일 수 μžˆμ§€λ§Œ, 이 μ§€μ μ—μ„œ κ³„μ†ν•΄μ„œ 이런 생각이 λ“€μ—ˆμŠ΅λ‹ˆλ‹€.

이미 μ΅μˆ™ν•œ 개발자 λ„κ΅¬μ˜ λ„€νŠΈμ›Œν¬ 탭을 κ·ΈλŒ€λ‘œ ν™œμš©ν•  μˆ˜λŠ” μ—†μ„κΉŒ?

msw-auto-mock: μžλ™ν™”λ˜μ—ˆμ§€λ§Œ μ—¬μ „νžˆ 손이 많이 κ°‘λ‹ˆλ‹€

msw-auto-mock은 api-recorder둜 λ…Ήν™”ν•œ 데이터λ₯Ό 기반으둜 MSW override ν•Έλ“€λŸ¬ μ½”λ“œλ₯Ό μžλ™ μƒμ„±ν•΄μ£ΌλŠ” λ„κ΅¬μž…λ‹ˆλ‹€. 이 도ꡬλ₯Ό ν™œμš©ν•΄ ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€λ³„λ‘œ λ„€νŠΈμ›Œν¬λ₯Ό λͺ©μ—…ν•  λ•ŒλŠ” λ‹€μŒκ³Ό 같은 과정을 거치게 λ©λ‹ˆλ‹€.

  1. api-recorderλ₯Ό μ‹€ν–‰ν•˜κ³  μ›ν•˜λŠ” μ‹œλ‚˜λ¦¬μ˜€λ₯Ό μˆ˜ν–‰ν•˜μ—¬ λ„€νŠΈμ›Œν¬ JSON νŒŒμΌμ„ μƒμ„±ν•©λ‹ˆλ‹€.
  2. μƒμ„±λœ νŒŒμΌμ„ ν”„λ‘œμ νŠΈ κ²½λ‘œμ— μ €μž₯ν•œ λ’€, μ–΄λ–€ μ‹œλ‚˜λ¦¬μ˜€μ— λ§€ν•‘ν• μ§€ μ„€μ •ν•©λ‹ˆλ‹€.
  3. msw-auto-mock λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•΄ override ν•Έλ“€λŸ¬λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ ν•˜λ‚˜λ₯Ό μΆ”κ°€ν•  λ•Œλ§ˆλ‹€ 이 μ„Έ 단계λ₯Ό λ°˜λ³΅ν•΄μ•Ό ν–ˆκ³ , 이 과정이 점점 번거둭게 λŠκ»΄μ‘ŒμŠ΅λ‹ˆλ‹€. 이미 JSON 데이터가 μžˆλŠ”λ°, ꡳ이 λ‹€μ‹œ μ½”λ“œλ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³  이 데이터λ₯Ό κ·ΈλŒ€λ‘œ λŸ°νƒ€μž„μ—μ„œ ν™œμš©ν•  μˆ˜λŠ” μ—†μ„κΉŒ? λΌλŠ” 생각이 λ“€μ—ˆμŠ΅λ‹ˆλ‹€.

ν…ŒμŠ€νŠΈ μ½”λ“œμ²˜λŸΌ λ‹¨μˆœ 반볡 μž‘μ—…μ΄ λ§Žμ€ μ˜μ—­μ—μ„œλŠ”, 단계 ν•˜λ‚˜λ₯Ό μ€„μ΄λŠ” κ²ƒλ§ŒμœΌλ‘œλ„ 체감 생산성이 크게 달라진닀고 λŠκΌˆμŠ΅λ‹ˆλ‹€.

e2e-autogen: 생성은 νŽΈν•˜μ§€λ§Œ μ‹€ν–‰ λ§₯락이 λΆ„λ¦¬λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€

e2e ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•  λ•ŒλŠ” 보톡 Playwright μ œλ„ˆλ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•΄ μ‹œλ‚˜λ¦¬μ˜€λ₯Ό κΈ°λ‘ν•˜λŠ”λ°, 이 λ‹¨κ³„μ—μ„œλŠ” λͺ©μ—…λœ 데이터λ₯Ό μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. mockApiResponseλŠ” ν…ŒμŠ€νŠΈ μ½”λ“œ μ‹€ν–‰ μ‹œμ μ—λ§Œ 적용되고, Playwright μ œλ„ˆλ ˆμ΄ν„°λŠ” ν…ŒμŠ€νŠΈ 싀행이 μ•„λ‹ˆλΌ 일반 λΈŒλΌμš°μ € 싀행이기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ "λͺ©λ‘μ— μ•„μ΄ν…œμ΄ ν•˜λ‚˜λ„ 없을 λ•Œ 빈 ν™”λ©΄ 문ꡬ가 λ…ΈμΆœλ˜μ–΄μ•Ό ν•œλ‹€"λŠ” μ‹œλ‚˜λ¦¬μ˜€λ₯Ό κ²€μ¦ν•˜λ €λ©΄,

  • msw-auto-mock으둜 빈 응닡에 λŒ€ν•œ λͺ©μ—…을 λ§Œλ“€μ–΄ Playwright μ œλ„ˆλ ˆμ΄ν„° μ‹œμ μ— ν™œμš©ν•˜κ³ , ν…ŒμŠ€νŠΈ μ½”λ“œ μ‹€ν–‰ μ‹œμ μ—λŠ” e2e-autogen의 mockApiResponse fixtureλ₯Ό μ‚¬μš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ 두 번의 μž‘μ—…μ„ ν•˜κ±°λ‚˜
  • Playwright μ œλ„ˆλ ˆμ΄ν„° μ‹€ν–‰ μ‹œμ μ—λŠ” UI μ½”λ“œλ₯Ό μž„μ‹œλ‘œ μˆ˜μ •ν•΄ ν™•μΈν•œ λ’€, ν…ŒμŠ€νŠΈ μ½”λ“œ μ‹€ν–‰ μ‹œμ μ—λŠ” λ‹€μ‹œ mockApiResponse fixtureλ₯Ό μ‚¬μš©ν•˜λŠ” λ°©μ‹μœΌλ‘œ μš°νšŒν•΄μ•Ό ν–ˆμŠ΅λ‹ˆλ‹€.

이 과정은 ν…ŒμŠ€νŠΈλ₯Ό λΉ λ₯΄κ²Œ μž‘μ„±ν•˜κ³  κ²€μ¦ν•˜κΈ°μ—λŠ” μ§€λ‚˜μΉ˜κ²Œ λ²ˆκ±°λ‘œμ› κ³ , κ²°κ΅­ 개발 흐름과 ν…ŒμŠ€νŠΈ μ‹€ν–‰ λ§₯락이 λΆ„λ¦¬λ˜μ–΄ μžˆλ‹€λŠ” 점이 κ°€μž₯ 큰 문제둜 λŠκ»΄μ‘ŒμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ 이 λΆˆνŽΈν•¨λ“€μ„ λ™μ‹œμ— ν•΄κ²°ν•  수 μžˆλŠ” ꡬ쑰가 ν•„μš”ν•˜λ‹€κ³  νŒλ‹¨ν–ˆμŠ΅λ‹ˆλ‹€.

κ°œμ„  아이디어

μ•žμ„œ μ–ΈκΈ‰ν•œ λΆˆνŽΈν•¨λ“€μ„ μ •λ¦¬ν•˜λ‹€ λ³΄λ‹ˆ, λ‹€μŒκ³Ό 같은 아이디어가 λ– μ˜¬λžμŠ΅λ‹ˆλ‹€.

  • e2e-autogen의 νŽΈλ¦¬ν•¨κ³Ό msw의 μœ μ—°ν•¨μ„ ν•©μΉ  수 μ—†μ„κΉŒ?
  • api-recorder둜 μƒμ„±ν•œ JSON 데이터λ₯Ό 기반으둜, μ½”λ“œλ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³ λ„ λŸ°νƒ€μž„μ— MSW ν•Έλ“€λŸ¬λ₯Ό λ™μ μœΌλ‘œ μ„ΈνŒ…ν•  수 μžˆλ‹€λ©΄ μ–΄λ–¨κΉŒ?

이λ₯Ό μœ„ν•΄ 각 ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€μ— λŒ€μ‘ν•˜λŠ” μ‹œλ‚˜λ¦¬μ˜€ λ§€ν•‘ νŒŒμΌμ„ 두고, ν•΄λ‹Ή μ‹œλ‚˜λ¦¬μ˜€λ₯Ό μ£Όμž…ν•˜λ©΄ λŸ°νƒ€μž„μ—μ„œ ν•„μš”ν•œ ν•Έλ“€λŸ¬κ°€ κ΅¬μ„±λ˜λŠ” ꡬ쑰λ₯Ό λ– μ˜¬λ ΈμŠ΅λ‹ˆλ‹€.

이 접근이 κ°€λŠ₯ν•˜λ‹€λ©΄,

  • msw-auto-mock처럼 사전 생성 과정을 κ±°μΉ˜μ§€ μ•Šμ•„λ„ 되고
  • e2e-autogen처럼 ν…ŒμŠ€νŠΈ μ‹€ν–‰ μ‹œμ λΏ μ•„λ‹ˆλΌ, κ°œλ°œΒ·λ””λ²„κΉ… λ‹¨κ³„μ—μ„œλ„ λ™μΌν•œ λͺ©μ—…을 μ‚¬μš©ν•  수 μžˆμ„ 것이라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

아이디어λ₯Ό κ΅¬μ²΄ν™”ν•˜λ©° μ•Œκ²Œ 된 HAR μŠ€νŽ™

μœ„ 생각을 λ°”νƒ•μœΌλ‘œ 아이디어λ₯Ό κ΅¬μ²΄ν™”ν•˜λ˜ 쀑, ν•œ κ°€μ§€ 질문이 μƒκ²ΌμŠ΅λ‹ˆλ‹€.

api-recorderλ₯Ό μ“°μ§€ μ•Šκ³ λ„, 이미 λΈŒλΌμš°μ €μ— μ°νžˆλŠ” λ„€νŠΈμ›Œν¬ 데이터λ₯Ό κ·ΈλŒ€λ‘œ ν™œμš©ν• λ§Œν•œ 방법은 μ—†μ„κΉŒ?

이 κ³Όμ •μ—μ„œ HAR(Http Archive)μŠ€νŽ™μ„ μ•Œκ²Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€. HAR νŒŒμΌμ€ λΈŒλΌμš°μ € 개발자 λ„κ΅¬μ˜ λ„€νŠΈμ›Œν¬ νƒ­μ—μ„œ κΈ°λ‘λ˜λŠ” μš”μ²­/응닡 정보λ₯Ό ν‘œμ€€ν™”λœ JSON 포맷으둜 μ €μž₯ν•œ νŒŒμΌμž…λ‹ˆλ‹€. 즉, κ°œλ°œμžκ°€ 이미 μ΅μˆ™ν•˜κ²Œ 보고 μžˆλŠ” λ„€νŠΈμ›Œν¬ 둜그λ₯Ό κ·ΈλŒ€λ‘œ 파일둜 μΆ”μΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.

HAR νŒŒμΌμ„ 기반으둜 api-recorderμ—μ„œ μ‚¬μš©ν•˜λŠ” JSON 포맷을 생성할 수 μžˆλ‹€λ©΄, λ³„λ„μ˜ api-recorder 라이브러리λ₯Ό μ„€μΉ˜ν•˜μ§€ μ•Šμ•„λ„ 되고, 개발자 λ„κ΅¬μ˜ λ„€νŠΈμ›Œν¬ νƒ­μ΄λΌλŠ” κΈ°μ‘΄ 흐름을 κ·ΈλŒ€λ‘œ μœ μ§€ν•  수 μžˆμ„ 것이라 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

κΈ°μ‘΄ κ΅¬μ‘°μ—μ„œ λ“œλŸ¬λ‚œ 문제점

ν•˜μ§€λ§Œ 이 아이디어λ₯Ό κΈ°μ‘΄ ꡬ쑰에 μ μš©ν•˜λ €κ³  ν•˜μž, ꡬ쑰적인 λ¬Έμ œλ“€μ΄ λ“œλŸ¬λ‚˜κΈ° μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€.

μ˜μ‘΄μ„± 문제

api-recorder에 쒅속됨 ν˜„μž¬ κ΅¬μ‘°μ—μ„œλŠ” e2e-autogen, msw-auto-mock이 api-recorderκ°€ μƒμ„±ν•œ 결과물의 νƒ€μž…κ³Ό μŠ€νŽ™μ— 직접 μ˜μ‘΄ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ¬Έμ œλŠ” 이 μ˜μ‘΄μ„±μ΄ 성격상 μ–΄μƒ‰ν•˜λ‹€λŠ” μ μ΄μ—ˆμŠ΅λ‹ˆλ‹€. 두 λΌμ΄λΈŒλŸ¬λ¦¬λŠ” api-recorder의 κΈ°λŠ₯을 μ‚¬μš©ν•˜μ§€ μ•Šκ³ , 였직 결과물의 ν˜•νƒœ(νƒ€μž…) 만 ν•„μš”λ‘œ ν•©λ‹ˆλ‹€. κ·ΈλŸΌμ—λ„ λΆˆκ΅¬ν•˜κ³  λ‹¨μˆœνžˆ νƒ€μž…μ„ μ°Έμ‘°ν•˜κΈ° μœ„ν•΄ api-recorderλ₯Ό μ’…μ†μ„±μœΌλ‘œ μ„€μΉ˜ν•˜λŠ” 것은 μ‚¬μš©μž μž…μž₯μ—μ„œ λ‚©λ“ν•˜κΈ° μ–΄λ €μš΄ ꡬ쑰라고 λŠκ»΄μ‘ŒμŠ΅λ‹ˆλ‹€.

특히 e2e-autogen, msw-auto-mock을 μ‚¬μš©ν•˜λŠ” μ‚¬μš©μž μ€‘μ—λŠ” api-recorderλ₯Ό μ „ν˜€ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” κ²½μš°λ„ 있기 λ•Œλ¬Έμ—, 이 μ˜μ‘΄μ„±μ€ λΆˆν•„μš”ν•œ 결합을 κ°•μ œν•˜λŠ” μ…ˆμ΄ λ©λ‹ˆλ‹€.

κ·Έλž˜μ„œ μž„μ‹œλ°©νŽΈμœΌλ‘œ μ„ νƒν•œ 방법이, api-recorder의 νƒ€μž… μ •μ˜λ₯Ό 각 라이브러리 내뢀에 λ³΅μ‚¬ν•΄μ„œ κ΄€λ¦¬ν•˜λŠ” λ°©μ‹μ΄μ—ˆμŠ΅λ‹ˆλ‹€. SSOF μœ„λ°°|605x399 ν•˜μ§€λ§Œ 이 방식은 λͺ…ν™•ν•˜κ²Œ Single Source of Truth 원칙을 μœ„λ°°ν•©λ‹ˆλ‹€. api-recorder의 νƒ€μž…μ΄ λ³€κ²½λ˜λ”λΌλ„ e2e-autogen, msw-auto-mockμ—μ„œλŠ” 이λ₯Ό μžλ™μœΌλ‘œ 인지할 수 μ—†κ³ , κ²°κ΅­ μ„Έ 곳의 μ½”λ“œλ₯Ό λͺ¨λ‘ μˆ˜μ •ν•΄μ•Ό ν•˜λŠ” ꡬ쑰가 λ©λ‹ˆλ‹€.

더 큰 λ¬Έμ œλŠ” μ˜μ‘΄μ„± λ°©ν–₯μ΄μ—ˆμŠ΅λ‹ˆλ‹€. κ°œλ…μ μœΌλ‘œ 보면 e2e-autogen, msw-auto-mock은 ν•˜μœ„ λͺ¨λ“ˆμ— 가깝고, api-recorder μ—­μ‹œ ν•˜λ‚˜μ˜ ν•˜μœ„ κ΅¬ν˜„μ²΄μ— λΆˆκ³Όν•©λ‹ˆλ‹€. 그런데 이 ν•˜μœ„ λͺ¨λ“ˆλ“€μ΄ μ„œλ‘œμ˜ λ‚΄λΆ€ ꡬ쑰λ₯Ό μ „μ œλ‘œ λ™μž‘ν•˜κ²Œ λ˜λ©΄μ„œ, 결과적으둜 ν•˜μœ„ λͺ¨λ“ˆλ“€λΌλ¦¬ κ°•ν•˜κ²Œ κ²°ν•©λœ μƒνƒœκ°€ λ˜μ–΄λ²„λ ΈμŠ΅λ‹ˆλ‹€.

이 κ΅¬μ‘°μ—μ„œλŠ” μ–΄λŠ ν•œ λͺ¨λ“ˆμ˜ 변경도 λ‹€λ₯Έ λͺ¨λ“  λͺ¨λ“ˆμ— 연쇄적인 영ν–₯을 쀄 μˆ˜λ°–μ— μ—†κ³ , ν™•μž₯μ΄λ‚˜ μŠ€νŽ™ 변경에 맀우 μ·¨μ•½ν•œ μƒνƒœλΌκ³  νŒλ‹¨ν–ˆμŠ΅λ‹ˆλ‹€.

har ν˜Έν™˜μ„± 문제

api-recorder λŒ€μ‹  κ°œλ°œμžλ„κ΅¬μ˜ har을 μ‚¬μš©ν•˜λ €λ©΄, har을 api-recorder와 ν˜Έν™˜λ˜λŠ” ν˜•μ‹μœΌλ‘œ λ°”κΎΈλŠ” 과정이 ν•„μš”ν•œλ°, 이 λ˜ν•œ 이 λ™μž‘μ„ μˆ˜ν–‰ν•΄μ£ΌλŠ” har-to-api-recorderλΌλŠ” 라이브러리λ₯Ό μΆ”κ°€λ‘œ λ§Œλ“€ κ³„νšμ„ μ„Έμ› μŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ—¬κΈ°μ„œ 또 ν•˜λ‚˜μ˜ 이상함이 λŠκ»΄μ‘ŒμŠ΅λ‹ˆλ‹€.

  • har-to-api-recorder
  • msw-auto-mock
  • e2e-autogen

이 μ„Έ λΌμ΄λΈŒλŸ¬λ¦¬λŠ” api-recorder의 κΈ°λŠ₯을 직접 μ‚¬μš©ν•˜μ§€ μ•ŠμŒμ—λ„ λΆˆκ΅¬ν•˜κ³ , λͺ¨λ‘ api-recorder의 μŠ€νŽ™ 변경에 영ν–₯을 λ°›λŠ” ꡬ쑰가 λ˜μ–΄ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ§Œμ•½ api-recorder의 μŠ€νŽ™μ΄ λ³€κ²½λœλ‹€λ©΄, μ—°μ‡„μ μœΌλ‘œ λͺ¨λ“  λΌμ΄λΈŒλŸ¬λ¦¬κ°€ 영ν–₯을 λ°›κ²Œ λ©λ‹ˆλ‹€.

κ²Œλ‹€κ°€ HAR νŒŒμΌμ—λŠ” api-recorderμ—λŠ” μ—†μ§€λ§Œ,

  • ν–₯ν›„ MSW λͺ©μ—…μ΄λ‚˜ ν…ŒμŠ€νŠΈμ— ν™œμš©ν•  수 μžˆμ„ λ²•ν•œ 정보듀이 μ‘΄μž¬ν–ˆκ³ 
  • 이λ₯Ό μŠ€νŽ™μ— ν¬ν•¨μ‹œν‚€κ³  μ‹Άμ—ˆμ§€λ§Œ
  • 이미 배포된 λΌμ΄λΈŒλŸ¬λ¦¬μ™€ μ‚¬μš©μžλ“€μ΄ μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ— λ§ˆμŒλŒ€λ‘œ λ³€κ²½ν•  수 μ—†λŠ” μƒν™©μ΄μ—ˆμŠ΅λ‹ˆλ‹€. 이 μ§€μ μ—μ„œ, 문제의 λ³Έμ§ˆμ€ 포맷 λ³€ν™˜μ΄ μ•„λ‹ˆλΌ κ΅¬μ‘°λΌλŠ” 결둠에 이λ₯΄λ €μŠ΅λ‹ˆλ‹€.

ν•΄κ²° 방법: μŠ€νŽ™μ„ μ€‘μ‹¬μœΌλ‘œ DIP 원칙 μ μš©ν•˜κΈ°

이 문제λ₯Ό ν’€κΈ° μœ„ν•΄ λ– μ˜¬λ¦° νžŒνŠΈλŠ” OpenAPI μŠ€νŽ™ κ΅¬μ‘°μ˜€μŠ΅λ‹ˆλ‹€.

OpenAPIλŠ” 2.0, 3.0, 3.1 λ“± μ—¬λŸ¬ λ²„μ „μ˜ μŠ€ν‚€λ§ˆκ°€ μ‘΄μž¬ν•˜μ§€λ§Œ, 이λ₯Ό 직접 μ²˜λ¦¬ν•˜κΈ°λ³΄λ‹€ swagger-parser 같은 라이브러리λ₯Ό 톡해 μ •κ·œν™”λœ ν˜•νƒœλ‘œ ν•΄μ„ν•©λ‹ˆλ‹€.

"μŠ€ν‚€λ§ˆμ˜ 버전 차이λ₯Ό κ°œλ³„ 도ꡬ가 직접 κ°λ‹Ήν•˜μ§€ μ•Šκ³ , κ³΅ν†΅λœ 해석 계측을 λ‘”λ‹€"

이 κ΅¬μ‘°μ—μ„œ 아이디어λ₯Ό μ–»μ–΄, λ„€νŠΈμ›Œν¬ λ‘œκ·Έλ„ 같은 λ°©μ‹μœΌλ‘œ λ‹€λ£¨κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€.

핡심 아이디어

  • api-recorderκ°€ μƒμ„±ν•œ 포맷을 μŠ€ν‚€λ§ˆ v1.0
  • HAR νŒŒμΌμ„ 기반으둜 μƒμ„±ν•œ 포맷을 μŠ€ν‚€λ§ˆ v1.1

둜 μ •μ˜ν•˜κ³ , 이 λ‹€μ–‘ν•œ μŠ€ν‚€λ§ˆλ₯Ό ν•΄μ„ν•˜κ³  μ •κ·œν™”ν•˜λŠ” μ½”μ–΄ 라이브러리λ₯Ό λΆ„λ¦¬ν•˜κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€. 이 μŠ€νŽ™μ˜ 이름을 network-log라고 λͺ…λͺ…ν–ˆμŠ΅λ‹ˆλ‹€.

network-log-core의 μ—­ν• 

|700x447

1. λ‹€μ–‘ν•œ ν˜•νƒœμ˜ μž…λ ₯을 단일 NetworkLog 포맷으둜 μ •κ·œν™”ν•©λ‹ˆλ‹€.

network-log-core의 핡심 μ§„μž…μ μ€ NetworkLogParserμž…λ‹ˆλ‹€. 이 ν•¨μˆ˜λ₯Ό 톡해raw 데이터가 api-recorder(v1.0)이든, HAR 기반으둜 μƒμ„±λœ v1.1 μŠ€ν‚€λ§ˆμ΄λ“  관계없이 항상 μ •κ·œν™”λœ NetworkLog ν˜•νƒœλ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€. 이 ꡬ쑰 덕뢄에 e2e-autogen, msw-auto-mock 같은 ν•˜μœ„ λͺ¨λ“ˆλ“€μ€ 데이터가 μ–΄λ””μ—μ„œ μ™”λŠ”μ§€λ₯Ό μ „ν˜€ μ‹ κ²½ μ“°μ§€ μ•Šκ³  항상 λ™μΌν•œ ν˜•μ‹μ˜ λ„€νŠΈμ›Œν¬ 둜그λ₯Ό κΈ°μ€€μœΌλ‘œ λ™μž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

즉,μž…λ ₯ 포맷의 닀양성은 network-log-coreμ—μ„œ ν‘μˆ˜ν•˜κ³ , ν•˜μœ„ λͺ¨λ“ˆμ€ ν•΄μ„λœ 결과만 λ°”λΌλ³΄λŠ” ꡬ쑰가 λ©λ‹ˆλ‹€.

2. network-log-coreλŠ” μ•ˆμ •μ μΈ λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€.

클린 μ•„ν‚€ν…μ²˜ κ΄€μ μ—μ„œ λ§ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈμ˜ μ•ˆμ •μ„±μ΄λž€, λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

λ‚˜λ₯Ό μ°Έμ‘°ν•˜λŠ” λͺ¨λ“ˆμ€ 많고, λ‚΄κ°€ μ°Έμ‘°ν•˜λŠ” λͺ¨λ“ˆμ€ μ μ„μˆ˜λ‘ μ•ˆμ •μ μ΄λ‹€ Stability = Fan-in / (Fan-in + Fan-out)

μ•ˆμ •μ μ΄λΌλŠ” 것은 κ³§ λ³€κ²½ν•˜κΈ° μ–΄λ ΅λ‹€λŠ” 의미이고, 그만큼 λ§Žμ€ μ½”λ“œκ°€ ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈ(배포 κ°€λŠ₯ν•œ μ΅œμ†Œ λ‹¨μœ„)에 μ˜μ‘΄ν•˜κ³  μžˆλ‹€λŠ” λœ»μ΄κΈ°λ„ ν•©λ‹ˆλ‹€.

network-log-coreλŠ” 이 기쀀을 λ§Œμ‘±ν•˜λ„λ‘ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

  • e2e-autogen, msw-auto-mock, api-recorder λ“± μ—¬λŸ¬ ν•˜μœ„ λͺ¨λ“ˆμ΄ 이λ₯Ό μ°Έμ‘°ν•˜μ§€λ§Œ
  • network-log-core μžμ²΄λŠ” μ™ΈλΆ€ κ΅¬ν˜„μ— μ˜μ‘΄ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€

κ·Έ κ²°κ³Ό, ν•˜μœ„ λͺ¨λ“ˆλ“€μ€ λ³€κ²½ κ°€λŠ₯성이 높은 κ΅¬ν˜„μ΄ μ•„λ‹ˆλΌ μ•ˆμ •μ μΈ μƒμœ„ μŠ€νŽ™(NetworkLog νƒ€μž…) μ—λ§Œ μ˜μ‘΄ν•˜κ²Œ λ˜μ—ˆκ³ , ꡬ쑰 전체가 변경에 훨씬 덜 μ·¨μ•½ν•΄μ‘ŒμŠ΅λ‹ˆλ‹€.

3. μ˜μ‘΄μ„±μ΄ μ—­μ „λ©λ‹ˆλ‹€.

이 κ΅¬μ‘°μ—μ„œλŠ” api-recorderλ‚˜ har-to-network-logκ°€ 자체적인 κΈ°μ€€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λŒ€μ‹ , network-log-coreκ°€ μ œμ‹œν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€μ™€ νƒ€μž…μ„ κΈ°μ€€μœΌλ‘œ κ΅¬ν˜„ν•©λ‹ˆλ‹€. 즉 ν•˜μœ„ κ΅¬ν˜„μ²΄(api-recorder, har-to-network-log)κ°€ μƒμœ„ λͺ¨λ“ˆμ΄ μ •μ˜ν•œ 계약을 κ΅¬ν˜„ν•˜λŠ” ꡬ쑰가 λ˜λ©΄μ„œ μ˜μ‘΄μ„±μ΄ λͺ…ν™•νžˆ μ—­μ „λ©λ‹ˆλ‹€. 클래슀 λ‹¨μœ„κ°€ μ•„λ‹ˆλΌ 라이브러리 λ‹¨μœ„μ—μ„œ DIPλ₯Ό μ μš©ν•œ 사둀라고 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.


μ •λ¦¬ν•˜μžλ©΄, μœ„ ꡬ쑰 덕뢄에 network-logλ₯Ό ν†΅ν•œ μƒνƒœκ³„λ₯Ό ν™•μž₯ν•΄λ‚˜κ°€λ”λΌλ„ κΈ°μ‘΄ ν•˜μœ„ λͺ¨λ“ˆλ“€μ€ μ „ν˜€ 영ν–₯을 λ°›μ§€ μ•Šκ³ , ν•˜μœ„ λͺ¨λ“ˆ κ°„ 직접적인 μ˜μ‘΄μ„±λ„ μ‚¬λΌμ‘ŒμœΌλ©° μƒˆλ‘œμš΄ μž…λ ₯ ν¬λ§·μ΄λ‚˜ ν™œμš© 도ꡬλ₯Ό μΆ”κ°€ν•˜κΈ°λ„ μš©μ΄ν•΄μ‘ŒμŠ΅λ‹ˆλ‹€.

마무리

이번 κΈ€μ—μ„œλŠ” λ„€νŠΈμ›Œν¬ 둜그 도ꡬ듀을 ν™•μž₯ν•˜λŠ” κ³Όμ •μ—μ„œ λ“œλŸ¬λ‚œ ꡬ쑰적 문제λ₯Ό μ–΄λ–»κ²Œ μ„€κ³„λ‘œ ν’€μ–΄λƒˆλŠ”μ§€ μ •λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€. λ‹€μŒ κΈ€μ—μ„œλŠ” 이 섀계λ₯Ό 기반으둜 μ‹€μ œ 라이브러리λ₯Ό κ΅¬ν˜„ν•œ κ³Όμ •κ³Ό μ½”λ“œ 레벨의 선택듀을 닀뀄볼 μ˜ˆμ •μž…λ‹ˆλ‹€.

이번 μ‚¬λ‘€λŠ” ν”„λ‘ νŠΈμ—”λ“œ ν™˜κ²½μ—μ„œ DIP(Dependency Inversion Principle) λ₯Ό μ μš©ν•œ κ²½ν—˜μ΄κΈ°λ„ ν•©λ‹ˆλ‹€. 클린 μ•„ν‚€ν…μ²˜μ—μ„œ λ§ν•˜λŠ” 원칙듀은 보톡 λ°±μ—”λ“œλ‚˜ 객체지ν–₯ μ–Έμ–΄ μ€‘μ‹¬μœΌλ‘œ μ„€λͺ…λ˜μ§€λ§Œ, 이번 μž‘μ—…μ„ 톡해 ν”„λ‘ νŠΈμ—”λ“œμ—μ„œλ„ λͺ¨λ“ˆ λ‹¨μœ„, μŠ€νŽ™ λ‹¨μœ„λ‘œ μΆ©λΆ„νžˆ 체감할 수 μžˆλ‹€λŠ” κ±Έ λŠκΌˆμŠ΅λ‹ˆλ‹€. 특히 μ»΄ν¬λ„ŒνŠΈ μ•ˆμ •λ„ κ΄€μ μ—μ„œ μ˜μ‘΄μ„±μ„ λ‹€μ‹œ λ°”λΌλ³΄κ²Œ 된 점이 인상 κΉŠμ—ˆμŠ΅λ‹ˆλ‹€.

졜근 클린 μ•„ν‚€ν…μ²˜λ₯Ό μ½μœΌλ©΄μ„œ "이걸 ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ 어디에 써먹을 수 μžˆμ„κΉŒ?"λΌλŠ” 고민을 많이 ν–ˆλŠ”λ°, μ½”λ“œ λ ˆλ²¨μ—μ„œλŠ” λ°”λ‘œ λ– μ˜€λ₯΄μ§€ μ•Šλ˜ 닡이 λͺ¨λ“ˆ 섀계 λ ˆλ²¨μ—μ„œ μžμ—°μŠ€λŸ½κ²Œ μ—°κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μš”μ¦˜μ€ AI 덕뢄에 μƒˆλ‘œμš΄ κΈ°μˆ μ„ λΉ λ₯΄κ²Œ ν•™μŠ΅ν•˜κ³  μ†ŒλΉ„ν•˜λŠ” κ²½ν—˜μ΄ λ§Žμ•„μ‘Œμ§€λ§Œ, 그럴수둝 이런 기본적인 섀계 원칙듀이 였히렀 더 큰 νž˜μ„ λ°œνœ˜ν•œλ‹€κ³  λŠλ‚λ‹ˆλ‹€. AIλ₯Ό 잘 ν™œμš©ν•˜κΈ° μœ„ν•΄μ„œλΌλ„, 가끔은 클린 μ•„ν‚€ν…μ²˜ 같은 책을 λ‹€μ‹œ 펼쳐보며 λ‚΄ 사고방식 자체λ₯Ό 천천히 μ—…λ°μ΄νŠΈν•˜λŠ” μ‹œκ°„μ΄ ν•„μš”ν•˜λ‹€λŠ” 생각이 λ“€μ—ˆμŠ΅λ‹ˆλ‹€.

ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ DIPλŠ” 어디에 μ“°μΌκΉŒ? μžλ™ν™” 도ꡬλ₯Ό μž¬μ„€κ³„ν•˜λ©° 얻은 μΈμ‚¬μ΄νŠΈ