이번에 프로젝트를 진행하면서 api를 디자인 하는데 참고하기 좋은 내용이어서 정리해보았습니다.
어떤 API든 Resource Oriented Desgin을 따르게 됩니다.
/systemOrders or /system_orders
/system-orders
/system-orders/{order_id} or /system-orders/{OrderId}
/system-orders/{orderId}
모든 유저의 리스트를 가져오는 경우,
GET /users (복수형)
GET /shops/:shopId/category/:categoryId/price
resource가 아닌 category의 property인 price를 가리키고 있습니다.
GET /shops/:shopId or GET /category/:categoryId
어떤 의도를 나타내려고 URL에서 동사를 쓰지 않습니다. 대신, 적절한 HTTP Method를 사용해서 기능을 설명할 수 있어야 합니다.
POST /updateuser/{userID} or GET /getusers
PUT /user/{userId}
만약, 특정 resource를 가리키는게 아니라 어떤 동작만 하는 endpoint의 경우에는, 동사를 사용할 수 있습니다.
ex) 유저에게 알람을 다시 보내는 경우
POST /alerts/245743/resend
이러한 operation들은 CRUD가 아니고, 특정한 작업을 수행하는 것들입니다.
request body나 response로 JSON을 사용하는 경우가 매우 많져. property는 camelCase로 씁시다.
{
user_name : "Junho Bae",
user_id : "1"
}
{
userName : "Junho Bae",
userId : "1"
}
RESTful HTTP 서비스는 /health, /version, /metrics 를 반드시 제공해야 합니다.
*health check?
잘 모르는 개념이라 찾아보니, 최근에는 많은 어플리케이션들을 클라우드 환경에서 운영하고 Micro Service로 개발을 합니다. 빠르고 표준화되어 서비스와 그 의존성들을 체크하기 위해서, health check API endpoint를 둔다고 합니다. 빠르게 해당 서비스의 상태와 지표 등등을 보내주는 endpoint 같습니다.
IBM health check document 를 보면 좋을 것 같습니다.
/debug, /status 등의 endpoint도 만드는 것이 매우 좋다고 합니다.
무튼간에, 내부적인 아키텍쳐를 노출하는 것은 좋을 일이 없기 떄문입니다.
현재 진행중인 Spring project에서는 Swagger를 사용하는데, Spring Rest Docs도 사용법을 익히면 좋을 것 같습니다.
항상 api에는 versioning을 해야 하고, 이 버전은 url의 맨 왼쪽에다 두어서, 가장 높은 범위를 가지게 해야 합니다.
이렇게 v1을 맨 앞에다 둬야 가장 넓은 범위를 가지게 되겠져?
버저닝을 안한다면, 만약 다른 곳에서 api를 쓰고 있는데 현재 api를 수정을 해버린다면 기능이 망가질 겁니다.
만약 어떤 오브젝트의 리스트를 반환한다면, response에다가 "total" property를 넣어줍시다.
{
users : [
...
],
total : 34
}
GET operation에는 limit와 offset을 두어, 페이지네이션을 할 수 있도록 열어둡시다.
GET /shops?offset=5&limit=5
응답할 데이터의 양 역시 로겨를 해야 합니다. fields 파라미터를 두고, 필요한 필드만 리턴할 수 있도록 합시다.
내 맘대로 dto에 때려박고 있는데..
GET /shops?fields =id,name,address,contact
이러면 name, address, contact 필드만 담아서 돌려줍니다. 이러면 response size를 줄이는데 도움이 될 수도 있습니다.
URL은 아주 자주 로그 기록이 남고, 그러면 authentication toeken도 불필요하게 로그 기록이 남을 겁니다. 매우 안좋습니다
GET /shops/123?token=some_kind_of_authentication_token
헤더에 넘깁시다.
Authorization : Bearer xxxxxx, Extra yyyy
당연히 토큰은 주기가 짧아야 합니다.
서버는 content type을 가정?(assume)하면 안됩니다. 가령, appliocation/x-www-form-urlencoded를 허용한다면, 공격자는 폼을 만들어서 post request를 날릴 겁니다.
따라서, 항상 content-type을 점증하고, 그냥 디폴트로 가고 싶다면 content-type:application/json을 받습니다.
http method는 CRUD 기능을 설명하는 목적이 있습니다.
예시는 다음과 같습니다.
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를 사용합니다.
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.
모든 엔드포인트, resource, service에 HTTPS를 적용해야 합니다.
에러 중에서 특히 서비스 에러는,
서비스가 요청을 거절하는 경우입니다.
이는 invalid authentication credentials, incorrect parameters, unknown version ID 등등이 예식 될 수 있습니다.