22가지 API Design 스킬

Junho Bae·2021년 4월 29일

Backend

목록 보기
1/1
post-thumbnail

betterprogramming.pub의 Mohammad Faisal님 원문

이번에 프로젝트를 진행하면서 api를 디자인 하는데 참고하기 좋은 내용이어서 정리해보았습니다.

용어

어떤 API든 Resource Oriented Desgin을 따르게 됩니다.

  • Resource : User와 같은 Data입니다.
  • Collection : Resourced의 집합을 의미합니다. User List와 같은 경우가 됩니다.
  • URL : Resource나 Collection의 위치를 나타냅니다. /user와 같은 경우입니다.

1. URL에는 kebab-case 사용한다.

안좋은 예

/systemOrders or /system_orders

좋은 예

/system-orders

2. Parameter에는 camelCase를 사용한다.

안좋은 예

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

좋은 예

/system-orders/{orderId}

3. Collection의 위치를 나타낼 때는 복수형을 쓴다.

모든 유저의 리스트를 가져오는 경우,

좋은 예

GET /users (복수형)

4. URL은 Collection에서 시작해서 식별자로 끝난다.

안좋은 예

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

resource가 아닌 category의 property인 price를 가리키고 있습니다.

좋은 예

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

5. Resource를 가리키는 URL에서 동사는 사용하지 않는다.

어떤 의도를 나타내려고 URL에서 동사를 쓰지 않습니다. 대신, 적절한 HTTP Method를 사용해서 기능을 설명할 수 있어야 합니다.

안좋은 예

POST /updateuser/{userID} or GET /getusers

좋은 예

PUT /user/{userId}

6. Non-Resource URL에서는 동사를 사용한다.

만약, 특정 resource를 가리키는게 아니라 어떤 동작만 하는 endpoint의 경우에는, 동사를 사용할 수 있습니다.
ex) 유저에게 알람을 다시 보내는 경우

POST /alerts/245743/resend

이러한 operation들은 CRUD가 아니고, 특정한 작업을 수행하는 것들입니다.

7. JSON property에는 camelCase를 쓰자.

request body나 response로 JSON을 사용하는 경우가 매우 많져. property는 camelCase로 씁시다.

나쁜 예

{
  user_name : "Junho Bae",
  user_id : "1"
}

좋은 예

{
  userName : "Junho Bae",
  userId : "1"
}

8. 모니터링

RESTful HTTP 서비스는 /health, /version, /metrics 를 반드시 제공해야 합니다.

  • /health : /health 요청에 200 OK status code로 응답을 합니다.

*health check?
잘 모르는 개념이라 찾아보니, 최근에는 많은 어플리케이션들을 클라우드 환경에서 운영하고 Micro Service로 개발을 합니다. 빠르고 표준화되어 서비스와 그 의존성들을 체크하기 위해서, health check API endpoint를 둔다고 합니다. 빠르게 해당 서비스의 상태와 지표 등등을 보내주는 endpoint 같습니다.

IBM health check document 를 보면 좋을 것 같습니다.

  • /version : 버전을 알려줍니다.
  • /metrics : 평균 응답시간 등과 같은 지표들을 알려줍니다.

/debug, /status 등의 endpoint도 만드는 것이 매우 좋다고 합니다.

9. Resource의 이름으로 table_name을 사용하지 않는다.

나쁜 예 : product_order

좋은 예 : product-orders

무튼간에, 내부적인 아키텍쳐를 노출하는 것은 좋을 일이 없기 떄문입니다.

10. API Design 툴을 사용하자.

  • API Blueprint
  • Swagger

현재 진행중인 Spring project에서는 Swagger를 사용하는데, Spring Rest Docs도 사용법을 익히면 좋을 것 같습니다.

11. 버전으로는 단순한 서수(Ordinal Number)를 사용하자.

항상 api에는 versioning을 해야 하고, 이 버전은 url의 맨 왼쪽에다 두어서, 가장 높은 범위를 가지게 해야 합니다.

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

이렇게 v1을 맨 앞에다 둬야 가장 넓은 범위를 가지게 되겠져?

버저닝을 안한다면, 만약 다른 곳에서 api를 쓰고 있는데 현재 api를 수정을 해버린다면 기능이 망가질 겁니다.

12. Response에는 Resource들의 Total Number를 포함해주자.

만약 어떤 오브젝트의 리스트를 반환한다면, response에다가 "total" property를 넣어줍시다.

좋은 예

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

13. limit와 offset 파라미터를 허용하자.

GET operation에는 limit와 offset을 두어, 페이지네이션을 할 수 있도록 열어둡시다.

GET /shops?offset=5&limit=5

14. 'fileds' Query 파라미터를 쓰자

응답할 데이터의 양 역시 로겨를 해야 합니다. fields 파라미터를 두고, 필요한 필드만 리턴할 수 있도록 합시다.

내 맘대로 dto에 때려박고 있는데..

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

이러면 name, address, contact 필드만 담아서 돌려줍니다. 이러면 response size를 줄이는데 도움이 될 수도 있습니다.

15. Authentication Token은 URL에 담지 말자

URL은 아주 자주 로그 기록이 남고, 그러면 authentication toeken도 불필요하게 로그 기록이 남을 겁니다. 매우 안좋습니다

안좋은 예

GET /shops/123?token=some_kind_of_authentication_token

좋은 예

헤더에 넘깁시다.

Authorization : Bearer xxxxxx, Extra yyyy

당연히 토큰은 주기가 짧아야 합니다.

16. Content-Type을 검증하자.

서버는 content type을 가정?(assume)하면 안됩니다. 가령, appliocation/x-www-form-urlencoded를 허용한다면, 공격자는 폼을 만들어서 post request를 날릴 겁니다.

따라서, 항상 content-type을 점증하고, 그냥 디폴트로 가고 싶다면 content-type:application/json을 받습니다.

17. CRUD Function에는 그에 맞는 HTTP Method를 사용하자

http method는 CRUD 기능을 설명하는 목적이 있습니다.

  • GET : 리소스 반환
  • POST : 리소스 생성
  • PUT : 기존의 리소스 업데이트
  • PATCH : 기존의 리소스를 업데이트 하나, 제공되는 필드만 업데이트하고 나머지는 그대로 둠.
  • DELETE : 리소스 삭제

18. Nested Resources를 위해서 URL에 Relation을 사용하자.

예시는 다음과 같습니다.

  • GET /shops/2/products : shop 2의 모든 상품들을 가져옵니다.

  • GET /shops/2/products/31 : shop 2에 속한 상품 31의 디테일 한 정보를 가져옵니다.

  • DELETE /shops/2/products/31 : shop2에 속한 product 31을 지웁니다.

  • PUT /shops/2/products/31 : 상품 31의 정보를 업데이트 하되, PUT은 Collection이 아닌 Resource-URL 에만 사용합니다.

  • POST /shops : 새로운 shop을 생성하고, 생성된 shop의 정보를 돌려줍니다. collection-URLs에는 Post를 사용합니다.

19. CORS

CORS(Cross-Origin Resource Sharing) 헤더를 지원해야 합니다.

Do support CORS (Cross-Origin Resource Sharing) headers for all public-facing APIs.
Consider supporting a CORS allowed origin of “*”, and enforcing authorization through valid OAuth tokens.
Avoid combining user credentials with origin validation.

20. Security

모든 엔드포인트, resource, service에 HTTPS를 적용해야 합니다.

21. Errors

에러 중에서 특히 서비스 에러는,

  1. 클라이언트가 invalid 하거나 incorrect한 요청을 서비스에 한 경우
  2. invalid 하거나 incorrect한 데이터를 서비스에 달한 경우

서비스가 요청을 거절하는 경우입니다.

이는 invalid authentication credentials, incorrect parameters, unknown version ID 등등이 예식 될 수 있습니다.

  • 4xx 에러코드를 반환한다.
  • 모든 속성을 처리하고 여러 validation problems를 하나의 응답에 담는 것 고려

22. Golden Rules, 황금률

  1. Flat is better than nested.
  2. Simple is better then complex
  3. Strings are better than numbers
  4. Consistency is beeter than customizaition
profile
SKKU Humanities & Computer Science

0개의 댓글