GoSuda

Go e l'ecosistema OpenAPI

By iwanhae
views ...

μ„œλ‘ 

Go μ–Έμ–΄λ‘œ Production Backend μ„œλ²„λ₯Ό κ°œλ°œν•˜λ‹€ 보면 거의 λŒ€λΆ€λΆ„μ˜ κ°œλ°œμžλ“€μ΄ κ°€μž₯ 처음으둜 λ§Œλ‚˜λŠ” λ‚œμ œ 쀑 ν•˜λ‚˜λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

API λ¬Έμ„œν™”, μ–΄λ–»κ²Œ ν•˜μ§€...?

이에 λŒ€ν•˜μ—¬ 쑰금만 찾아보면 OpenAPI μŠ€νŽ™μ— λ§žλŠ” λ¬Έμ„œλ₯Ό μž‘μ„±ν•˜λŠ” 것이 μ΄λ‘­λ‹€λŠ” 사싀을 κΉ¨λ‹«κ²Œ 되고, μžμ—°μŠ€λŸ½κ²Œ OpenAPI와 μ—°λ™λ˜λŠ” 라이브러리λ₯Ό 찾게 λ©λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ΄λŸ¬ν•œ 결정을 μ„Έμ›Œλ„ κ·Έ λ‹€μŒ λ¬Έμ œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

OpenAPI κ΄€λ ¨ 라이브러리 λ§Žμ€λ°.. 뭐 μ¨μ•Όν•˜μ§€...?

이 λ¬Έμ„œλŠ” μ΄λŸ¬ν•œ 상황을 κ²½ν—˜ν•˜κ³  계신 Go μž…λ¬Έμžλ“€μ„ μœ„ν•˜μ—¬ μž‘μ„±ν•œ κ°„λž΅ν•œ 라이브러리 μ†Œκ°œκΈ€ μž…λ‹ˆλ‹€. 2024λ…„ 말 κΈ°μ€€μœΌλ‘œ μž‘μ„±λœ λ¬Έμ„œμ΄λ©°, μ–Έμ–΄ μƒνƒœκ³„λŠ” 항상 μœ λ™μ μœΌλ‘œ λ°”λ€ŒλŠ” 만큼 μ°Έκ³ ν•˜λ©΄μ„œ 항상 μ΅œμ‹  근황도 μ‚΄νŽ΄λ³΄λŠ”κ²ƒμ„ μΆ”μ²œλ“œλ¦½λ‹ˆλ‹€.

OpenAPI λ₯Ό λŒ€ν•˜λŠ” λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ˜ μ „λž΅

이미 μ•Œκ³ κ³„μ‹  λΆ€λΆ„μ΄κ² μ§€λ§Œ, OpenAPI λŠ” REST APIλ₯Ό λͺ…ν™•ν•˜κ²Œ μ •μ˜ν•˜κ³  λ¬Έμ„œν™”ν•˜κΈ° μœ„ν•œ μŠ€νŽ™μž…λ‹ˆλ‹€. API의 μ—”λ“œν¬μΈνŠΈ, μš”μ²­, 응닡 ν˜•μ‹ 등을 YAML λ˜λŠ” JSON ν˜•μ‹μœΌλ‘œ μ •μ˜ν•˜μ—¬ κ°œλ°œμžλ“€ 뿐만 μ•„λ‹ˆλΌ ν”„λ‘ νŠΈλ‹¨, λ°±μ—”λ“œλ‹¨ μ½”λ“œ 생성을 μžλ™ν™”ν•˜μ—¬ λ¬΄μ˜λ―Έν•œ λ°˜λ³΅μ„ 쀄여주고 μ†Œμ†Œν•œ νœ΄λ¨Όμ—λŸ¬λ“€μ„ μ€„μ—¬μ£ΌλŠ”λ° 큰 도움을 μ€λ‹ˆλ‹€.

μ΄λŸ¬ν•œ OpenAPI λ₯Ό ν”„λ‘œμ νŠΈμ™€ μžμ—°μŠ€λŸ½κ²Œ κ²°ν•©μ‹œν‚€κΈ° μœ„ν•΄ Go μƒνƒœκ³„μ˜ λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ€ 크게 λ‹€μŒ μ„Έκ°€μ§€ μ „λž΅μ„ μ·¨ν•©λ‹ˆλ‹€.

1. Go 주석을 OpenAPI μŠ€νŽ™ λ¬Έμ„œλ‘œ μ‘°ν•©

OpenAPI 에 λ§žμΆ°μ„œ API λ₯Ό κ°œλ°œν• λ•Œ κΉŒλ‹€λ‘œμš΄μ  쀑 ν•˜λ‚˜λŠ” μ‹€μ œ λ¬Έμ„œμ™€ ν•΄λ‹Ή λ¬Έμ„œλ₯Ό κ΅¬ν˜„ν•œ μ½”λ“œκ°€ λ³„λ„μ˜ 파일둜 μ „ν˜€ λ‹€λ₯Έμœ„μΉ˜μ— μ‘΄μž¬ν•˜λ‹€λ³΄λ‹ˆ, μ½”λ“œλ₯Ό μ—…λ°μ΄νŠΈ ν–ˆλŠ”λ° λ¬Έμ„œλ₯Ό μ—…λ°μ΄νŠΈ μ•ˆν–ˆλ˜κ°€ λ¬Έμ„œλŠ” μ—…λ°μ΄νŠΈ ν–ˆλŠ”λ° μ½”λ“œλ₯Ό μ—…λ°μ΄νŠΈ ν•˜μ§€ λͺ»ν•˜λŠ” 상황이 생각보닀 μž¦λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

κ°„λ‹¨ν•œ μ˜ˆμ‹œλ₯Ό 듀어보면

  1. ./internal/server/user.go λΌλŠ” 파일 μ†μ—μ„œ API 에 λŒ€ν•œ λ‘œμ§μ„ μˆ˜μ •ν–ˆλŠ”λ°
  2. μ‹€μ œ λ¬Έμ„œλŠ” ./openapi3.yaml 에 μ‘΄μž¬ν•˜κ³ , μ΄μ—λŒ€ν•œ 변경을 μ‹€μˆ˜λ‘œ κΉœλΉ‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  3. μ΄λŸ¬ν•œ 변경사항에 λŒ€ν•œ 이슈λ₯Ό μΈμ§€ν•˜μ§€ λͺ»ν•˜κ³  Pull Request λ₯Ό 날리고 λ™λ£Œλ“€μ—κ²Œ 리뷰λ₯Ό 받을 경우
  4. 리뷰어듀 λ˜ν•œ ./openapi3.yaml 에 λŒ€ν•œ 변경사항이 λˆˆμ— 보이지 μ•ŠκΈ° λ•Œλ¬Έμ— API μŠ€νŽ™μ€ κ·ΈλŒ€λ‘œμΈλ° μ‹€μ œ API κ΅¬ν˜„μ²΄λŠ” 변경이 λ˜μ–΄λ²„λ¦¬λŠ” λΆˆμƒμ‚¬κ°€ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Go μ£Όμ„μ˜ ν˜•νƒœλ‘œ API λ¬Έμ„œλ₯Ό μž‘μ„±ν•˜λ©΄ μ΄λŸ¬ν•œ 문제λ₯Ό μ–΄λŠ 정도 ν•΄μ†Œν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ½”λ“œμ™€ λ¬Έμ„œκ°€ ν•œ 곳에 λͺ¨μ—¬ 있기 λ•Œλ¬Έμ—, μ½”λ“œλ₯Ό μˆ˜μ •ν•˜λ©΄μ„œ 주석도 ν•¨κ»˜ μ—…λ°μ΄νŠΈν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ 주석을 기반으둜 μžλ™μœΌλ‘œ OpenAPI μŠ€νŽ™ λ¬Έμ„œλ₯Ό μƒμ„±ν•΄μ£ΌλŠ” 도ꡬ듀이 μ‘΄μž¬ν•©λ‹ˆλ‹€.

λŒ€ν‘œμ μΈ ν”„λ‘œμ νŠΈλ‘œλŠ” Swagκ°€ μžˆμŠ΅λ‹ˆλ‹€. SwagλŠ” Go μ½”λ“œμ˜ 주석을 νŒŒμ‹±ν•˜μ—¬ OpenAPI 2 ν˜•μ‹μ˜ λ¬Έμ„œλ₯Ό 생성해 μ€λ‹ˆλ‹€. μ‚¬μš© 방법은 κ°„λ‹¨ν•©λ‹ˆλ‹€. ν•Έλ“€λŸ¬ ν•¨μˆ˜ μœ„μ— 각 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ μ •ν•œ ν˜•μ‹μ— 맞게 주석을 μž‘μ„±ν•˜λ©΄ λ©λ‹ˆλ‹€.

 1// @Summary μœ μ € 생성
 2// @Description μƒˆλ‘œμš΄ μœ μ €λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
 3// @Tags Users
 4// @Accept json
 5// @Produce json
 6// @Param user body models.User true "μœ μ € 정보"
 7// @Success 200 {object} models.User
 8// @Failure 400 {object} models.ErrorResponse
 9// @Router /users [post]
10func CreateUser(c *gin.Context) {
11    // ...
12}

μ΄λ ‡κ²Œ 주석을 μž‘μ„±ν•˜λ©΄ Swag λΌλŠ” CLI λŠ” 이 주석듀을 νŒŒμ‹±ν•΄μ„œ OpenAPI 2 λ¬Έμ„œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. 일반적으둜 CI 과정에 μ΄λŸ¬ν•œ μž‘μ—…μ΄ ν–‰ν•΄μ§€λ©°, μƒμ„±λœ OpenAPI μŠ€νŽ™μ˜ λ¬Έμ„œλŠ” Git Repository, μ΅œμ’… λΉŒλ“œ κ²°κ³Όλ¬Ό, λ³„λ„μ˜ μ™ΈλΆ€ API λ¬Έμ„œ 관리 μ‹œμŠ€ν…œμ— λ°°ν¬λ˜μ–΄ λ‹€λ₯Έ ν”„λ‘œμ νŠΈμ™€μ˜ ν˜‘μ—…λ•Œ μ‚¬μš©λ˜κ²Œ λ©λ‹ˆλ‹€.

μž₯점:

  • 주석이 μ½”λ“œμ™€ ν•¨κ»˜ 있기 λ•Œλ¬Έμ— μ‹€μ œ μ½”λ“œμ™€ λ¬Έμ„œμ˜ ν˜•μƒμ΄ λ‹¬λΌμ§ˆ κ°€λŠ₯성이 μ€„μ–΄λ“­λ‹ˆλ‹€.
  • λ³„λ„μ˜ λ„κ΅¬λ‚˜ λ³΅μž‘ν•œ μ„€μ • 없이 μ£Όμ„λ§ŒμœΌλ‘œ κ°„νŽΈν•˜κ³  자유둭게 λ¬Έμ„œν™”λ₯Ό ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 주석이 μ‹€μ œ API λ‘œμ§μ— 영ν–₯을 μ£Όμ§„ μ•ŠκΈ°λ•Œλ¬Έμ—, λ¬Έμ„œλ‘œ κ³΅κ°œν•˜κΈ° λΆ€λ‹΄μŠ€λŸ¬μš΄ μž„μ‹œ κΈ°λŠ₯을 μΆ”κ°€ν•˜κΈ° μ’‹μŠ΅λ‹ˆλ‹€.

단점:

  • μ£Όμ„μ˜ λΌμΈμˆ˜κ°€ λ§Žμ•„μ§€λ©΄μ„œ 단일 μ½”λ“œ νŒŒμΌμ— λŒ€ν•œ 가독성이 λ–¨μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ£Όμ„μ˜ ν˜•νƒœλ‘œ λͺ¨λ“  API μŠ€νŽ™μ„ ν‘œν˜„ν•˜κΈ° μ–΄λ €μšΈ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • λ¬Έμ„œκ°€ μ½”λ“œλ₯Ό κ°•μ œν•˜λŠ”κ²ƒμ€ μ•„λ‹ˆκΈ°λ•Œλ¬Έμ— OpenAPI λ¬Έμ„œμ™€ μ‹€μ œ 둜직이 μΌμΉ˜ν•œλ‹€λŠ” 보μž₯을 ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

2. OpenAPI μŠ€νŽ™μ˜ λ¬Έμ„œλ‘œ Go μ½”λ“œλ₯Ό 생성

Single source of Truth (SSOT) λ₯Ό Go μ½”λ“œκ°€ μ•„λ‹ˆλΌ λ¬Έμ„œμͺ½μ— λ‘λŠ” 방법도 μ‘΄μž¬ν•©λ‹ˆλ‹€. λ°”λ‘œ OpenAPI μŠ€νŽ™μ„ λ¨Όμ € μ •μ˜ν•˜κ³ , μ •μ˜λœ λ‚΄μš©μ„ 기반으둜 Go μ½”λ“œλ₯Ό μƒμ„±ν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€. API μŠ€νŽ™μ΄ κ³§ μ½”λ“œλ₯Ό 생성해주기 λ•Œλ¬Έμ— 개발 λ¬Έν™”μ μœΌλ‘œ API 섀계λ₯Ό λ¨Όμ € ν•˜λŠ”κ²ƒμ„ κ°•μ œν•  수 있으며 개발 μˆœμ„œμ μœΌλ‘œ API μŠ€νŽ™μ„ μ •μ˜ν•˜λŠ”κ²ƒμ΄ κ°€μž₯λ¨Όμ € μ‹œμž‘μ΄ λ˜κΈ°λ•Œλ¬Έμ— 개발이 μ™„λ£Œλ˜κ³  λ‚˜μ„œμ•Ό λ†“μΉœλΆ€λΆ„μ„ μΈμ§€ν•˜κ³  API μŠ€νŽ™ λ³€κ²½κ³Ό ν•¨κ»˜ 전체 μ½”λ“œκ°€ μˆ˜μ •λ˜λŠ” λΆˆμƒμ‚¬λ₯Ό 쑰기에 λ°©μ§€ν•  수 μžˆλŠ” 강점을 κ°€μ§€κ³  μžˆμŠ΅λ‹ˆλ‹€.

이 방식을 μ±„νƒν•˜λŠ” λŒ€ν‘œμ μΈ ν”„λ‘œμ νŠΈλ‘œλŠ” oapi-codegen κ³Ό OpenAPI Generator κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€. μ‚¬μš©λ²•μ€ κ°„λ‹¨ν•©λ‹ˆλ‹€.

  1. OpenAPI μŠ€νŽ™μ— 맞게 yaml ν˜Ήμ€ json λ¬Έμ„œλ₯Ό μž‘μ„±ν•˜κ³ 
  2. CLI λ₯Ό μ‹€ν–‰ν•˜λ©΄
  3. 그에 λŒ€μ‘λ˜λŠ” Go stub μ½”λ“œκ°€ μƒμ„±λ©λ‹ˆλ‹€.
  4. 이제 이 stub 이 μ‚¬μš©ν•  수 μžˆλ„λ‘ κ°œλ³„ API 에 λŒ€ν•œ μ„ΈλΆ€ 둜직만 직접 κ΅¬ν˜„ν•˜λ©΄ λ©λ‹ˆλ‹€.

λ‹€μŒμ€ oapi-codegen μ—μ„œ μƒμ„±ν•΄μ£ΌλŠ” μ½”λ“œμ˜ μ˜ˆμ‹œμž…λ‹ˆλ‹€.

1// StrictServerInterface represents all server handlers.
2type StrictServerInterface interface {
3	// ...
4	// Returns all pets
5	// (GET /pets)
6	FindPets(ctx context.Context, request FindPetsRequestObject) (FindPetsResponseObject, error)
7	// ...
8}

μœ„ interface λ₯Ό 맀개둜 oapi-codegen 이 생성해쀀 μ½”λ“œλŠ” query parameters, header, body νŒŒμ‹± 및 Validation λ“±μ˜ λ‘œμ§μ„ μˆ˜ν–‰ν•˜κ³  interface 에 μ„ μ–Έλœ μ μ ˆν•œ method λ₯Ό ν˜ΈμΆœν•΄μ£ΌλŠ” κ΅¬μ‘°μž…λ‹ˆλ‹€. μ‚¬μš©μžλŠ” μœ„ interface 에 λŒ€ν•œ κ΅¬ν˜„μ²΄λ§Œ κ΅¬ν˜„ν•˜λ©΄ API κ΅¬ν˜„μ— ν•„μš”ν•œ μž‘μ—…μ΄ μ™„λ£Œλ˜κ²Œ λ©λ‹ˆλ‹€.

μž₯점:

  • μŠ€νŽ™μ΄ λ¨Όμ € λ‚˜μ˜€κ³  개발이 μ§„ν–‰λ˜κΈ° 떄문에 μ—¬λŸ¬ νŒ€μ—μ„œ ν˜‘μ—…ν•˜λŠ”κ²½μš° 업무λ₯Ό λ³‘λ ¬μ μœΌλ‘œ μ§„ν–‰ν•˜κΈ° μœ λ¦¬ν•©λ‹ˆλ‹€.
  • λ°˜λ³΅μ„± λ…Έκ°€λ‹€λ‘œ μž‘μ—…ν•˜λ˜ 뢀뢄에 λŒ€ν•œ μ½”λ“œκ°€ μžλ™μœΌλ‘œ μƒμ„±λ˜κΈ° λ•Œλ¬Έμ—, 업무 효율이 μƒμŠΉν•˜λ©΄μ„œλ„ 디버깅에 μ—¬μ „νžˆ μœ λ¦¬ν•©λ‹ˆλ‹€.
  • λ¬Έμ„œμ™€ μ½”λ“œμ˜ ν˜•μƒμ΄ 항상 μΌμΉ˜ν•˜λ‹€λŠ”κ²ƒμ„ 보μž₯ν•˜κΈ° μ‰½μŠ΅λ‹ˆλ‹€.

단점:

  • OpenAPI μŠ€νŽ™ μžμ²΄μ— λ¬΄μ§€ν•œ μƒνƒœμΌκ²½μš° 초기 λŸ¬λ‹μ»€λΈŒκ°€ λ‹€μ†Œ μ‘΄μž¬ν•©λ‹ˆλ‹€.
  • API λ₯Ό ν•Έλ“€λ§ν•˜λŠ” μ½”λ“œμ˜ ν˜•μƒμ΄ ν”„λ‘œμ νŠΈμ— μ˜ν•΄μ„œ μžλ™μœΌλ‘œ μƒμ„±λ˜κΈ° 떄문에 μ»€μŠ€ν„°λ§ˆμ΄μ§•μ΄ ν•„μš”ν•œκ²½μš° λŒ€μ‘ν•˜κΈ° μ–΄λ €μšΈ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ €μžμ˜ μ½”λ©˜νŠΈ. 2024λ…„ 10μ›” κΈ°μ€€ OpenAPI Generator κ°€ μƒμ„±ν•œ Go μ½”λ“œλŠ” API 둜직뿐만 μ•„λ‹ˆλΌ 전체 ν”„λ‘œμ νŠΈ ν˜•μƒμ„ κ°•μ œν•˜λ©° ν”„λ‘œμ νŠΈμ˜ ꡬ쑰가 κ²½μ§λ˜μ–΄μžˆμ–΄ μ‹€μ œ Production ν™˜κ²½μ— ν•„μš”ν•œ λ‹€μ–‘ν•œ κΈ°λŠ₯듀을 μΆ”κ°€ν•˜κΈ°μ—λŠ” λΆ€μ ν•©ν•œ ν˜•νƒœμ˜ μ½”λ“œλ₯Ό μƒμ„±ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 이 방식을 μ±„νƒν•˜μ‹œλŠ” 뢄듀은 oapi-codegen 을 μ‚¬μš©ν•˜μ‹œλŠ”κ²ƒμ„ 적극적으둜 ꢌμž₯λ“œλ¦½λ‹ˆλ‹€. μ €μžλŠ”, oapi-codege + echo + StrictServerInterface λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

3. Go μ½”λ“œλ‘œ OpenAPI μŠ€νŽ™ λ¬Έμ„œλ₯Ό 생성

μˆ˜μ‹­, 수백λͺ…μ˜ μ‚¬λžŒλ“€μ΄ 같은 μ„œλ²„μ—λŒ€ν•΄μ„œ κ°œλ°œμ„ μ§„ν–‰ν•˜λ‹€λ³΄λ©΄ ν•„μ—°μ μœΌλ‘œ λ°œμƒν•˜λŠ” μ΄μŠˆκ°€ κ°œλ³„ API λ³„λ‘œ 톡일성이 깨질 수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 직관적인 μ˜ˆμ‹œλ‘œ 100κ°œκ°€ λ„˜μ–΄κ°€λŠ” API Endpoint 에 λŒ€ν•œ λͺ…μ„Έλ₯Ό ν•˜λ‚˜μ˜ OpenAPI yaml νŒŒμΌμ— μ„ μ–Έν• κ²½μš° ν•΄λ‹Ή νŒŒμΌμ€ 1만 라인이 λ„˜μ–΄κ°€λŠ” 괴물이 λ˜μ–΄μžˆμ„ 것이고 μƒˆλ‘œμš΄ API Endpoint λ₯Ό μ„ μ–Έν•˜λ©΄μ„œ ν•„μ—°μ μœΌλ‘œ 같은 λͺ¨λΈμ„ μ€‘λ³΅ν•΄μ„œ μ„ μ–Έν•œλ‹€λ˜κ°€ λͺ‡λͺ‡ ν•„λ“œλ₯Ό λˆ„λ½ν•œλ‹€λ˜κ°€, μ»¨λ²€μ…˜μ— λ§žμ§€ μ•ŠλŠ” Path 넀이밍이 νƒ„μƒν•œλ‹€λ˜κ°€μ™€ 같은 전체저인 API 의 톡일성이 κΉ¨μ§€κΈ° μ‹œμž‘ν•˜κ²Œ λ©λ‹ˆλ‹€.

μ΄λŸ¬ν•œ 이슈λ₯Ό ν•΄κ²°ν•˜κΈ°μœ„ν•΄ OpenAPI yaml 을 κ΄€λ¦¬ν•˜λŠ” Owner λ₯Ό λ”°λ‘œ λ‘”λ‹€λ˜κ°€, Linter λ₯Ό κ°œλ°œν•΄μ„œ CI 과정쀑에 μžλ™μœΌλ‘œ μž‘μ•„λ‚Ό 수 μžˆλ„λ‘ 쑰치λ₯Ό μ·¨ν• μˆ˜λ„ μžˆκ² μ§€λ§Œ Go μ–Έμ–΄λ‘œ Domain-specific language (DSL) λ₯Ό μ •μ˜ν•˜μ—¬ λͺ¨λ“  API κ°€ 일관적인 톡일성을 κ°€μ§ˆ 수 μžˆλ„λ‘ κ°•μ œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ 기법을 μ‚¬μš©ν•˜λŠ” λŒ€ν‘œμ μΈ ν”„λ‘œμ νŠΈκ°€ Kubernetes 이며 (별도 라이브러리 없이 자체적으둜 ꡬ좕), go-restful, goa λ“±μ˜ ν”„λ‘œμ νŠΈλ₯Ό μ‚¬μš©ν•΄μ„œ μ‚¬μš©ν•΄λ³Όμˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒμ€ goa 의 μ‚¬μš© μ˜ˆμ‹œμž…λ‹ˆλ‹€.

 1var _ = Service("user", func() {
 2    Method("create", func() {
 3        Payload(UserPayload)
 4        Result(User)
 5        HTTP(func() {
 6            POST("/users")
 7            Response(StatusOK)
 8        })
 9    })
10})

μœ„μ™€κ°™μ΄ 컴파일 κ°€λŠ₯ν•œ Go μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ©΄ POST /users API 에 λŒ€ν•œ κ΅¬ν˜„κ³Ό λ¬Έμ„œμ— λŒ€ν•œ μ •μ˜κ°€ λ™μ‹œμ— μ™„λ£Œλ˜λŠ” 강점을 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

μž₯점:

  • μ½”λ“œλ‘œλΆ€ν„° λͺ¨λ“ κ²Œ λ‚˜μ˜€κΈ°λ•Œλ¬Έμ— ν”„λ‘œμ νŠΈ 전체에 λŒ€ν•œ API 일관성을 κ°€μ§€κ³ κ°€κΈ°κ°€ μ‰½μŠ΅λ‹ˆλ‹€.
  • Go 의 κ°•νƒ€μž… μ‹œμŠ€ν…œμ„ ν™œμš©ν•˜μ—¬, OpenAPI3 의 λͺ¨λ“  κΈ°λŠ₯을 ν™œμš©ν–ˆμ„λ•Œλ³΄λ‹€ 더 μ •ν™•ν•˜κ³  λ…Όλž€μ΄ μ—†λŠ” μŠ€νŽ™μ„ 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

단점:

  • 각 ν”„λ ˆμž„μ›Œν¬μ—μ„œ μ •μ˜ν•œ DSL 을 μ΅ν˜€μ•Όν•˜λ©°, κΈ°μ‘΄ μ½”λ“œμ— μ μš©ν•˜κΈ°λŠ” μ–΄λ €μšΈ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • ν”„λ ˆμž„μ›Œν¬μ—μ„œ μ œμ•ˆν•œ κ·œμΉ™μ„ κ°•μ œλ‘œ 따라야 ν•˜λ―€λ‘œ μžμœ λ„ 및 μœ μ—°μ„±μ΄ λ–¨μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

λ§ˆλ¬΄λ¦¬ν•˜λ©°

각 방법은 μž₯단점이 있으며, ν”„λ‘œμ νŠΈμ˜ μš”κ΅¬μ‚¬ν•­κ³Ό νŒ€μ˜ μ„ ν˜Έλ„μ— 따라 μ ν•©ν•œ 방법을 μ„ νƒν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€. μ–Έμ œλ‚˜ 제일 μ€‘μš”ν•œκ²ƒμ€ μ–΄λ–€ 방식을 μ‚¬μš©ν•˜λŠ”κ²Œ μ’‹μœΌλƒκ°€ μ•„λ‹ˆλΌ, ν˜„μž¬ μžμ‹ μ΄ μ²˜ν•œ 상황에 κ°€μž₯ μ ν•©ν•œ μ†”λ£¨μ…˜μ€ 무엇인지 κ°€μΉ˜νŒλ‹¨μ„ μˆ˜ν–‰ν•˜κ³  개발 생산성을 λ†’κ²Œ κ°€μ Έκ°€ λΉ λ₯Έ 퇴근과 흑쑱슀러운 μ›ŒλΌλ²¨μ„ μ¦κΈ°λŠ” κ²ƒμž…λ‹ˆλ‹€.

ν˜„μž¬ 2024λ…„ 10월을 κΈ°μ€€μœΌλ‘œ 글을 μž‘μ„±ν•˜κΈ΄ ν–ˆμ§€λ§Œ Go와 OpenAPI μƒνƒœκ³„λŠ” μ§€μ†μ μœΌλ‘œ λ°œμ „ν•˜κ³  μžˆμœΌλ―€λ‘œ, 이 글을 μ½λŠ” μ‹œμ κ°„μ˜ 간격을 κ³ λ €ν•˜μ—¬ 각 λΌμ΄λΈŒλŸ¬λ¦¬λ“€ 및 ν”„λ‘œμ νŠΈλ“€μ˜ κ·Όν™©κ³Ό κ·Έλ“€μ˜ λ³€κ²½λœ μž₯단점도 μ§€μ†μ μœΌλ‘œ νŒ”λ‘œμ—…ν•˜μ‹œκΈΈ λ°”λžλ‹ˆλ‹€.

ν–‰λ³΅ν•œ Go 라이프 λ˜μ„Έμš”~ 😘