API 디자인

리소스를 중심으로 디자인 됩니다. 리소스는 클라이언트에서 액세스할 수 있는 모든 종류의 개체, 데이터 또는 서비스이빈다.

리소스마다 고유하게 식별하는 URI인 식별자가 있습니다. 예를 들어 특정 고객 주문의 URI는 다음과 같습니다.

https://adventure-works.com/orders/1

자원은 4가지 범주로 분류할 수 있다.

문서

DB에서의 하나의 레코드, Spring에서의 하나의 객체와 유사한 단일 자원의 개념입니다. 단수를 사용하여 문서 자원을 표시합니다.

http://api.example.com/**device-management**/managed-devices/{device-id}  
http://api.example.com/**user-management**/users/{id}  
http://api.example.com/**user-management**/users/admin

컬렉션

서버가 관리하는 리소스 디렉터리입니다. 복수형으로 작성합니다.

http://api.example.com/device-management/**managed-devices**  
http://api.example.com/user-management/**users**  
http://api.example.com/user-management/**users**/{id}/**accounts**

스토어

스토어는 클라이언트가 관리 하는 자원 저장소이다. 클라이언트는 API를 이용하여 자원을 넣거나 가져올 수 있고 삭제 할 수 있다. 복수를 사용하여 스토어를 표현한다.

http://api.example.com/song-management/users/{id}/**playlists**

컨트롤러

컨트롤러 자원은 인자와 반환 값, 입력 및 출력이 있는 실행 가능한 함수와 같다. 문서, 컬렉션, 스토어로 해결이 어려운 절차적 실행을 수행하기 위한 모델이다. 특정 자원을 가리키는 것이 아니라 실행 인 만큼 예외적으로 동사를 사용한다.

http://api.example.com/cart-management/users/{id}/cart/**checkout**  
http://api.example.com/song-management/users/{id}/playlist/**play**

자원의 필터링을 위해서는 쿼리 파라미터를 사용한다.

자원을 정렬, 필터링 하거나 제한된 수량을 요청 해야 할 필요가 있다. 이때 신규 API를 생성 하려 하지 말고 쿼리 파라미터를 활용 한다.

http://api.example.com/device-management/managed-devices  
http://api.example.com/device-management/managed-devices?**region=USA**  
http://api.example.com/device-management/managed-devices?**region=USA&brand=XYZ**  
http://api.example.com/device-management/managed-devices?**region=USA&brand=XYZ&sort=installation-date**
  • Paging : 리턴해야하는 데이터의 양이 많거나 예측하기 어려운경우는 페이징 처리를 하는것이 좋다.
  • Filtering : 속성의 기대값을 지정하여 리소스를 필터링한다. 하나의 속성에 여러개의 기대값으로 필터링하는것이 가능하며 한번에 여러개의 속성으로 필터링 하는것도 가능하다.
  • Sorting : 리소스를 정렬한다. sort 파라미터는 정렬을 수행할 속성의 이름을 포함해야 한다.
  • Searching : 검색 파라미터는 Filter와 유사하게 전달되지만 정확한 값이 아니여도 되며 대략적으로 일치하기만 하면 된다.

대부분의 경우 camelCase보다는 -을 사용합니다.

http://api.example.com/devicemanagement/manageddevices/ http://api.example.com/device-management/managed-devices

REST API에서는 일관된 소문자를 권장합니다. 복합어 형태로 이뤄진 경우 -로 가독성을 챙깁니다. 단, 언더바(_)는 사용하지 않습니다. 애플리케이션의 글꼴에 따라 일부 브라우저나 화면에서 정상적으로 표시되지 않을 수 있습니다.

캐싱을 표현하기

안좋은 사례

리소스의 작업이 아닌 리소스를 기반으로 작성해야한다.

https://adventure-works.com/orders // Good

https://adventure-works.com/create-order // Avoid

컬렉션을 참조하는 URI에 대해서는 일관적인 명명 규칙을 적용해야 한다.

메서드를 적극적으로 활용하자

GET : 리소스 접근
POST : 리소스 생성
PUT: 리소스에 대한 전체 속성 업데이트
PATCH: 리소스 일부 속성 업데이트
DELETE: 지정된 URI 리소스 제거

리소스POSTGETPUTDELETE
/customers새 고객 만들기모든 고객 검색고객 전체 업데이트고객 전체 제거
/customers/1-id=1인 고객 검색고객1의 세부 정보 업데이트고객 1 제거
/customers/1/orders고객 1의 주문 생성id=1인 고객의 주문 내역 검색고객 1의 주문 전체 업데이트고객 1의 모든 주문 내역 제거
  • POST 요청은 기존 리소스에 처리할 데이터를 보내는데 사용할 수 있음

각 메서드별 고려해야 하는 응답 코드

POST

  • 새 리소스가 정상 생성된 경우 -> 201 or 200
  • 새 리소스가 정상 생성되었으나 body에 포함할 내용이 없는 경우 -> 204(내용없음)

PUT

GET에는 Body를 잘 사용하지 않는다.

  1. HTTP 표준:

    • HTTP/1.1 표준(RFC 7231)은 GET 요청에서 본문을 사용하지 않는 것을 명시적으로 요구하지 않지만, GET 요청은 자원의 상태를 변경하지 않고 자원의 표현을 요청하는 데 사용된다고 명시하고 있습니다.
    • GET 요청은 주로 URL을 통해 필요한 모든 정보를 전달하는 것으로 간주됩니다. 따라서 쿼리 파라미터를 통해 정보를 전달하는 것이 일반적입니다.
  2. 호환성 문제:

    • 많은 웹 서버, 프록시, 캐시 및 브라우저는 GET 요청의 본문을 무시하거나 제대로 처리하지 않습니다. 이는 GET 요청이 본문을 포함하지 않는다는 가정하에 설계되었기 때문입니다.
    • 만약 GET 요청에 본문이 포함된 경우, 이러한 인프라 컴포넌트는 예기치 않게 동작할 수 있으며, 이는 호환성 문제를 초래할 수 있습니다.
  3. 안정성과 멱등성:

    • GET 요청은 멱등성(idempotent)을 가지며, 동일한 요청을 여러 번 수행해도 동일한 결과를 반환해야 합니다. 이는 주로 URL을 통해 필요한 모든 정보를 전달함으로써 보장됩니다.
    • 본문을 포함한 GET 요청은 멱등성을 깨뜨릴 수 있으며, 서버 측에서 처리의 일관성을 보장하기 어렵게 만들 수 있습니다.
  4. 캐싱:

    • GET 요청은 캐싱이 가능하다는 특성이 있습니다. 캐시는 URL을 기준으로 작동하므로, 쿼리 파라미터를 통해 전달된 정보가 캐시 키로 사용될 수 있습니다.
    • 본문을 포함한 GET 요청은 캐시 인프라에서 제대로 처리되지 않으며, 이는 캐싱의 이점을 활용할 수 없게 만듭니다.

이름 지정 규칙

오랜 시간이 지나더라도 일반적인 개발자 환경을 제공하려면 다음과 같아야합니다.
1: 단순해야합니다.
2: 직관적이어야 합니다.
3: 일관적이어야 합니다.

  • 정확한 미국 영어여야합니다.
  • 일반적으로 인정되는 줄임말 또는 축약어를 사용할 수 있습니다. (Application Programming Interface - API)