λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
μŠ€ν„°λ”” & μ„Έλ―Έλ‚˜

22 Best Practices to Take Your API Design Skills to the Next Level

by 주발2 2021. 9. 16.
λ°˜μ‘ν˜•

πŸ“Ž 22 Best Practices to Take Your API Design Skills to the Next Level

  • λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€μ˜ μ„Έκ³„μ—μ„œλŠ” λ°±μ—”λ“œ API에 λŒ€ν•œ μΌκ΄€λœ 섀계가 ν•„μˆ˜μ μž…λ‹ˆλ‹€.

 

https://betterprogramming.pub/22-best-practices-to-take-your-api-design-skills-to-the-next-level-65569b200b9

 

22 Best Practices to Take Your API Design Skills to the Next Level

Practical advices for designing REST APIs

betterprogramming.pub

μœ„ 원문을 λ²ˆμ—­ν•œ ν¬μŠ€νŒ…μž…λ‹ˆλ‹€.

 

 

 

First, Some Terminology


Resource Oriented Design 이라고 λΆˆλ¦¬λŠ” λͺ¨λ“  API의 λ””μžμΈμ€ μ•„λž˜ μ„Έ 가지 핡심 κ°œλ…μœΌλ‘œ ꡬ성이 λ©λ‹ˆλ‹€.

  • Resource(λ¦¬μ†ŒμŠ€): λ¦¬μ†ŒμŠ€λŠ” User와 같은 λ°μ΄ν„°μ˜ μ‘°κ°μž…λ‹ˆλ‹€. 
  • Collection(μ»¬λ ‰μ…˜): μ»¬λ ‰μ…˜μ€ User의 리슀트(λͺ©λ‘)κ³Ό 같은 λ¦¬μ†ŒμŠ€μ˜ 그룹을 μ˜λ―Έν•©λ‹ˆλ‹€.
  • URL: λ¦¬μ†ŒμŠ€ λ˜λŠ” μ»¬λ ‰μ…˜μ˜ μœ„μΉ˜λ₯Ό μ‹λ³„ν•©λ‹ˆλ‹€. (ex: /user)

 

 

1. Use kebab-case for URLs


 

μ£Όλ¬Έ λͺ©λ‘μ„ κ°€μ Έμ˜€λ €λŠ” 경우 λ‹€μŒκ³Ό 같은 쒋은 μ˜ˆμ‹œμ™€ λ‚˜μœ μ˜ˆμ‹œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

 

Good:

/system-orders

 

Bad:

/systemOrders
/system_orders

 

 

2. Use camelCase for Parameters


νŠΉμ • μƒμ μ—μ„œ μ œν’ˆμ„ κ°€μ Έμ˜€λŠ” 경우 λ‹€μŒκ³Ό 같은 쒋은 μ˜ˆμ‹œμ™€ λ‚˜μœ μ˜ˆμ‹œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

 

Good:

/system-orders/{orderId}

 

Bad:

/system-orders/{order_id}
/system-orders/{OrderId}

 

 

3. Plural Name to Point to a Collection


μ‹œμŠ€ν…œμ˜ λͺ¨λ“  μœ μ €(λ³΅μˆ˜ν˜•)λ₯Ό μ‘°νšŒν•˜κΈ° μœ„ν•΄ λ‹€μŒκ³Ό 같은 쒋은 μ˜ˆμ‹œμ™€ λ‚˜μœ μ˜ˆμ‹œκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

 

Good:

GET /users

 

Bad:

GET /user
GET /User

 

 

4. URL Starts With a Collection and Ends With an Identifier


컨셉을 λ…νŠΉν•˜κ³  μΌκ΄€λ˜κ²Œ μœ μ§€ν•˜λ €λŠ” 경우 μ‹λ³„μžλ‘œ λλ‚˜μ•Ό ν•©λ‹ˆλ‹€.

 

Good:

GET /shops/:shopId/ 
GET /category/:categoryId

 

Bad:

GET /shops/:shopId/category/:categoryId/price

 

 

5. Keep Verbs Out of Your Resource URL


URLμ—μ„œ μ˜λ„λ₯Ό ν‘œν˜„ν•˜κΈ° μœ„ν•΄ 동사λ₯Ό μ‚¬μš©ν•˜μ§€ λ§ˆμ„Έμš”. λŒ€μ‹ , μ μ ˆν•œ HTTP λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μž‘μ—…μ„ μ„€λͺ…ν•©λ‹ˆλ‹€.

 

Good:

PUT /user/{userId}

 

Bad:

POST /updateuser/{userId}
GET /getusers

 

 

6. Use Verbs for Non-Resource URL


μž‘μ—…λ§Œ λ°˜ν™˜ν•˜λŠ” μ—”λ“œν¬μΈνŠΈκ°€ μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ 경우 동사λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • 예λ₯Ό λ“€μ–΄, μ‚¬μš©μžμ—κ²Œ κ²½κ³ λ₯Ό λ‹€μ‹œ λ³΄λ‚΄λ €λŠ” 경우

 

Good:

POST /alerts/245743/resend

μœ„ URL은 CRUD μž‘μ—…μ΄ μ•„λ‹ˆλΌ μ‹œμŠ€ν…œμ—μ„œ νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” κΈ°λŠ₯으둜 κ°„μ£Όλ©λ‹ˆλ‹€.

 

 

7. Use camelCase for JSON property


μš”μ²­ λ³Έλ¬Έ λ˜λŠ” 응닡이 JSON인 μ‹œμŠ€ν…œμ„ κ΅¬μΆ•ν•˜λ €λŠ” 경우, 속성 ν•„λ“œλŠ” μΉ΄λ©œμΌ€μ΄μŠ€μ—¬μ•Ό ν•©λ‹ˆλ‹€.

 

Good:

{
   userName: "Mohammad Faisal"
   userId: "1"
}

 

Bad:

{
   user_name: "Mohammad Faisal"
   user_id: "1"
}

 

 

8. Monitoring


RESTful HTTP μ„œλΉ„μŠ€λŠ” /health, /version, /metrics의 API μ—”λ“œν¬μΈνŠΈλ₯Ό κ΅¬ν˜„ν•΄μ•Ό ν•˜λ©°, μ΄λŠ” λ‹€μŒ 정보λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

 

/health

  • /health의 μš”μ²­μ— λŒ€ν•΄ 200 OK의 μƒνƒœμ½”λ“œλ‘œ μ‘λ‹΅ν•©λ‹ˆλ‹€.

 

/version

  • /version의 μš”μ²­μ— λŒ€ν•΄ 버전 번호둜 μ‘λ‹΅ν•©λ‹ˆλ‹€.

 

/metrics

  • /metrics APIλŠ” 평균 응닡 μ‹œκ°„κ³Ό 같은 λ‹€μ–‘ν•œ λ§€νŠΈλ¦­μ„ μ œκ³΅ν•©λ‹ˆλ‹€.

 

 

9. Don't Use table_name for the Resource Name


ν…Œμ΄λΈ” 이름을 λ¦¬μ†ŒμŠ€ μ΄λ¦„μœΌλ‘œ μ‚¬μš©ν•˜μ§€ λ§ˆμ„Έμš”. μž₯κΈ°μ μœΌλ‘œλŠ” μœ„ν—˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

Good:

product-orders

 

Bad:

product_orders

 

 

10. API λ””μžμΈ 도ꡬ μ‚¬μš©


λ‹€μŒκ³Ό 같은 쒋은 λ¬Έμ„œν™”λ₯Ό μœ„ν•œ 쒋은 API λ””μžμΈνˆ΄μ΄ 많이 μ‘΄μž¬ν•©λ‹ˆλ‹€.

ν›Œλ₯­ν•˜κ³  μƒμ„Έν•œ λ¬Έμ„œν™”λŠ” API μ†ŒλΉ„μžμ—κ²Œ ν›Œλ₯­ν•œ μ‚¬μš©μž κ²½ν—˜(UX)λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

 

 

11. Use Simple Ordinal Number as Version


항상 API에 버저닝을 μ‚¬μš©ν•˜κ³ , κ°€μž₯ 높은 λ²”μœ„λ₯Ό 가지도둝 ν•˜μ„Έμš”. 버전 λ²ˆν˜ΈλŠ” v1, v2 등등이어야 ν•©λ‹ˆλ‹€.

 

Good:

http://api.domain.com/v1/shops/3/products

APIκ°€ μ™ΈλΆ€ μ—”ν‹°ν‹°μ—μ„œ μ‚¬μš©μ€‘μΈ 경우 μ—”λ“œν¬μΈνŠΈλ₯Ό λ³€κ²½ν•˜λ©΄ κΈ°λŠ₯이 쀑단될 수 μžˆμœΌλ―€λ‘œ 항상 API에 λŒ€ν•œ 버저닝을 μ‚¬μš©ν•˜μ„Έμš”.

 

 

12. Include Total Number of Resources in Your Response


APIκ°€ 객체 λͺ©λ‘μ„ λ¦¬ν„΄ν•˜λŠ” 경우 응닡 항상 응닡에 λ¦¬μ†ŒμŠ€μ˜ 총 갯수λ₯Ό 포함해야 ν•©λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ total 속성을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

Good:

{
  users: [ 
     ...
  ],
  total: 34
}

 

Bad:

{
  users: [ 
     ...
  ]
}

 

 

13. Accept limit and offset Parameters


GET μž‘μ—…μ—μ„œλŠ” 항상 limit, offset νŒŒλΌλ―Έν„°λ₯Ό λ°›μŠ΅λ‹ˆλ‹€.

 

Good:

GET /shops?offset=5&limit=5

μ΄λŠ” ν”„λ‘ νŠΈ μ—”λ“œμ—μ„œμ˜ νŽ˜μ΄μ§€ λ„€μ΄μ…˜μ— ν•„μš”ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

 

 

14. Take fields Query Parameter


λ°˜ν™˜λ˜λŠ” λ°μ΄ν„°μ˜ 양도 κ³ λ €ν•΄μ•Ό ν•©λ‹ˆλ‹€. APIμ—μ„œ ν•„μˆ˜ ν•„λ“œλ§Œ λ…ΈμΆœν•˜λ„λ‘ λ§€κ°œλ³€μˆ˜λ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

λ‹€μŒ μ˜ˆμ‹œλŠ” μƒ΅μ˜ id, 이름, μ£Όμ†Œ, μ—°λ½μ²˜λ§Œ λ°˜ν™˜ν•˜λŠ” API μž…λ‹ˆλ‹€.

 

Good:

GET /shops?fields=id,name,address,contact

λ˜ν•œ κ²½μš°μ— 따라 응닡 크기λ₯Ό μ€„μ΄λŠ” 데 도움이 λ©λ‹ˆλ‹€.

 

 

15. Don't Pass Authentication Tokens in URL


μ’…μ’… URL이 기둝되고 인증 토큰도 λΆˆν•„μš”ν•˜κ²Œ 기둝되기 λ•Œλ¬Έμ— μ΄λŠ” 맀우 λ‚˜μœ λ°©λ²•μž…λ‹ˆλ‹€.

URL λŒ€μ‹  Header와 ν•¨κ»˜ μ „λ‹¬ν•˜μ„Έμš”.

 

Good:

Authorization: Bearer xxxxxx, Extra yyyyy

 

Bad:

GET /shops/123?token=some_kind_of_authenticaiton_token

 

 

16. Validate the Content-Type


μ„œλ²„λŠ” Content-Type을 ν™•μ‹ ν•΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ application/x-www-form-urlencoded 에 λŒ€ν•΄ μˆ˜λ½ν•œλ‹€λ©΄, κ³΅κ²©μžλŠ” 양식을 λ§Œλ“€κ³  κ°„λ‹¨ν•œ POST μš”μ²­μ„ 톡해 트리거λ₯Ό ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

17. Use HTTP Methods for CRUD Functions


HTTP λ©”μ†Œλ“œλŠ” CRUD κΈ°λŠ₯을 μ„€λͺ…ν•˜κΈ° μœ„ν•œ λͺ©μ μœΌλ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.

  •  GET : μžμ›μ˜ ν‘œν˜„μ„ κ²€μƒ‰ν•©λ‹ˆλ‹€.
  •  POST : μƒˆλ‘œμš΄ μžμ›κ³Ό ν•˜μœ„ μžμ›μ„ μƒμ„±ν•©λ‹ˆλ‹€.
  •  PUT : κΈ°μ‘΄ μžμ›μ„ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€.
  •  PATCH : κΈ°μ‘΄ μžμ›μ„ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€. 제곡된 ν•„λ“œλ§Œ μ—…λ°μ΄νŠΈν•˜λ©° λ‚˜λ¨Έμ§€ ν•„λ“œλŠ” κ·ΈλŒ€λ‘œ λ‘‘λ‹ˆλ‹€.
  •  DELETE : κΈ°μ‘΄ λ¦¬μ†ŒμŠ€λ₯Ό μ‚­μ œν•©λ‹ˆλ‹€.

 

 

18. Use the Relation in the URL For Nested Resources


쀑첩 λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ URL 관계 μ‚¬μš©μ— λŒ€ν•œ λͺ‡λͺ‡ μ‹€μš©μ μΈ μ˜ˆλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  •  GET /shops/2/products : 2번 Shop의 λͺ¨λ“  μ œν’ˆ 리슀트λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
  •  GET /shops/2/products/31 : 2번 Shop에 μ†ν•œ 31번 μƒν’ˆμ˜ 정보λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.
  •  DELETE /shops/2/products/31 : 2번 Shop에 μ†ν•œ 31번 μƒν’ˆμ„ μ‚­μ œν•©λ‹ˆλ‹€.
  •  PUT /shops/2/products/31 : 2번 Shop에 μ†ν•œ 31번 μƒν’ˆμ„ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€. 
  •  POST /shops : μƒˆ Shop을 λ§Œλ“€κ³  μƒμ„±λœ μƒˆ μƒμ μ˜ μ„ΈλΆ€ 정보λ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•©λ‹ˆλ‹€. 

 

 

19. CORS


λͺ¨λ“  곡개 API에 λŒ€ν•΄ CORS(Cross-Origin Resource Sharing) 헀더λ₯Ό μ§€μ›ν•©λ‹ˆλ‹€.

CORS ν—ˆμš© 좜처 "*"을 μ§€μ›ν•˜κ³ , μœ νš¨ν•œ OAuth tokens을 톡해 κΆŒν•œ λΆ€μ—¬λ₯Ό ν•˜λŠ” 것을 κ³ λ €ν•˜μ„Έμš”.

 

 

20. Security


λͺ¨λ“  μ—”λ“œν¬μΈνŠΈ, λ¦¬μ†ŒμŠ€ 및 μ„œλΉ„μŠ€μ—μ„œ HTTPS(TLS-encrypted)λ₯Ό μ‹œν–‰ν•©λ‹ˆλ‹€.

λͺ¨λ“  콜백 URL, ν‘Έμ‹œ μ•Œλ¦Ό, μ—”λ“œν¬μΈνŠΈ, 웹훅에 λŒ€ν•΄ HTTPSλ₯Ό μ‹œν–‰ν•˜κ³  μš”κ΅¬ν•©λ‹ˆλ‹€.

 

 

21. Errors


 

였λ₯˜ 및 μ„œλΉ„μŠ€ 였λ₯˜λŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ μœ νš¨ν•˜μ§€ μ•Šκ±°λ‚˜ μ„œλΉ„μŠ€μ— λŒ€ν•΄ 잘λͺ»λœ μš”μ²­μ„ ν•˜κ±°λ‚˜, 잘λͺ»λœ 데이터λ₯Ό μ„œλΉ„μŠ€μ— μ „λ‹¬ν•˜κ³  μ„œλΉ„μŠ€κ°€ μš”μ²­μ„ κ±°λΆ€ν•  λ•Œ λ°œμƒν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ 잘λͺ»λœ 인증 자격 증λͺ…, 잘λͺ»λœ λ§€κ°œλ³€μˆ˜, μ•Œ 수 μ—†λŠ” 버전 ID 등이 μžˆμŠ΅λ‹ˆλ‹€.

  • ν•˜λ‚˜ μ΄μƒμ˜ μ„œλΉ„μŠ€ 였λ₯˜λ‘œ 인해 ν΄λΌμ΄μ–ΈνŠΈ μš”μ²­μ„ κ±°λΆ€ν•  λ•Œ  4xx  HTTP 였λ₯˜ μ½”λ“œλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • λͺ¨λ“  속성을 μ²˜λ¦¬ν•œ ν›„ 단일 μ‘λ‹΅μœΌλ‘œ μ—¬λŸ¬ μœ νš¨μ„± 검사λ₯Ό λ°˜ν™˜ν•˜λŠ” 것을 κ³ λ €ν•˜μ„Έμš”.

 

 

22. Golden Rules


API λ””μžμ—”μ•  λŒ€ν•΄ 확신이 μ„œμ§€ μ•ŠλŠ” 경우 λ‹€μŒκ³Ό 같은  Golden Rules λŠ” μ˜¬λ°”λ₯Έ 결정을 λ‚΄λ¦¬λŠ” 데 도움이 될 수 μžˆμŠ΅λ‹ˆλ‹€.

  • ν”Œλž«μ€ 쀑첩보닀 λ‚«μŠ΅λ‹ˆλ‹€.
  • λ‹¨μˆœν•œ 것이 λ³΅μž‘ν•œ 것보닀 λ‚«μŠ΅λ‹ˆλ‹€.
  • μˆ«μžλ³΄λ‹€ λ¬Έμžμ—΄μ΄ μ’‹μŠ΅λ‹ˆλ‹€.
  • 일관성은 μ‚¬μš©μž μ •μ˜λ³΄λ‹€ λ‚«μŠ΅λ‹ˆλ‹€.

 

 

정리


원문을 기반으둜 APIλ₯Ό λ””μžμΈν•˜λŠ” 22κ°€μ§€μ˜ Best Practices에 λŒ€ν•΄ λ²ˆμ—­κΈ€μ„ μž‘μ„±ν•΄λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

REST API 섀계λ₯Ό κ³ λ €ν•˜λ‹€ 보면 ν¬μŠ€νŒ…μ— μ‘΄μž¬ν•˜λŠ” λŒ€λΆ€λΆ„μ˜ λ‚΄μš©λ“€μ— λŒ€ν•΄ ν•œ λ²ˆμ”© κ³ λ €ν• λ§Œν•œ μ‚¬ν•­λ“€μž…λ‹ˆλ‹€.

μ •λ¦¬ν•˜λ©΄μ„œ ν₯λ―Έλ‘œμ› λ˜ λ²ˆν˜ΈλŠ” 6 7 8 12 14 16 μž…λ‹ˆλ‹€.

  • 6. Use Verbs for Non-Resource URL
  • 7. Use camelCase for JSON property
  • 8. Monitoring
  • 12. Include Total Number of Resources in Your Response
  • 14. Take fields Query Parameter
  • 16. Validate the Content-Type

λ¦¬ν€˜μŠ€νŠΈ, λ¦¬μŠ€ν°μŠ€κ°€ JSON ν˜•μ‹μ΄λΌλ©΄ 속성 값은 μΉ΄λ©œμΌ€μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λΌλŠ” 점, ν—¬μŠ€μ²΄ν¬λ‚˜ 버전관리, 맀트릭 등에 λŒ€ν•œ API 제곡, 응닡 객체의 총 갯수λ₯Ό 같이 λ°˜ν™˜ν•˜λŠ” 점, Content-Type에 λŒ€ν•œ μœ νš¨μ„± 검사 λ“± λ‹€μ–‘ν•œ 방법에 λŒ€ν•΄μ„œλ„ 배울 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

 

λ°˜μ‘ν˜•

λŒ“κΈ€