RESTful API - 자원 모델링

SeungHyuk Shin·2022년 2월 24일
0

API는 종종 인터페이스 및 메서드를 중심으로 디자인됩니다. 시간이 지나면서 인터페이스와 메서드가 점차 많아지면 개발자가 각 메서드를 따로 배워야 하기 때문에 결국 API 표면이 지나치게 커져 혼동을 초래할 수 있습니다. 이는 분명 시간 낭비일 뿐만 아니라 오류가 쉽게 발생하는 원인이 됩니다.

REST의 아키텍처 스타일은 기본적으로 HTTP/1.1을 효과적으로 사용하도록 디자인하기 위해 도입되었지만 이러한 문제를 해결하는 데도 유용합니다. 주요 원칙은 소수의 메서드를 사용해 조작할 수 있도록 이름이 지정된 리소스를 정의하는 것입니다. 리소스와 메서드는 API의 명사와 동사로 알려져 있습니다. 리소스 이름은 HTTP 프로토콜을 통해 자연적으로 URL에 매핑되고 메서드는 자연적으로 HTTP 메서드인 POST, GET, PUT, PATCH, DELETE에 매핑됩니다.

이에 따라 학습해야 할 내용이 크게 줄어들어 개발자는 리소스와 리소스 관계에 집중할 수 있습니다. 단 표준 메서드가 동일하게 적은 수라는 가정을 전제로 합니다.

Gmail API 예제

Gmail API
Gmail API 서비스는 Gmail API를 구현하며 Gmail 기능 대부분을 제공합니다. 리소스 모델은 다음과 같습니다.

API 서비스: gmail.googleapis.com
사용자 컬렉션: users/- 각 사용자는 다음과 같은 리소스를 갖습니다.
메시지 컬렉션: users/-/messages/-
스레드 컬렉션: users/-/threads/-
라벨 컬렉션: users/-/labels/-
변경 내역 컬렉션: users/-/history/-
사용자 프로필을 나타내는 리소스: users/-/profile
사용자 설정을 나타내는 리소스: users/-/settings

관계와 하위 자원

리소스는 RESTful API 설계의 기본 단위입니다. 리소스는 애플리케이션 데이터 모델의 개체를 모델링합니다. 리소스는 거의 항상 다른 리소스와 관계가 있습니다.

API 소비자가 API를 어떻게 사용하는지 링크를 통해 직접 설명하는 API를 제공하는 것입니다.

관계를 위한 하이퍼미디어 지원 응답...

  • 링크 요소를 자체에게 반환해야 합니다.
  • 하위 리소스에 대한 링크를 반환해야 합니다.
  • 관련 개체에 대한 링크를 반환해야

예제 요청

GET /invoices/INV-567A89HG1

예제 응답

{
  "_links":
	{
    "self": { "href": "{baseurl}/invoices/INV-567A89HG1"},
    "customer": { "href": "{baseurl}/customer/CUST-12ATCVWV"},
    "collection/lineitems": { "href": "{baseurl}/invoices/INV-567A89HG1/lineitems"},
    "collection/payments": { "href": "{baseurl}/invoices/INV-567A89HG1/payments"},
  },
  "id": "INV-567A89HG1",
  "number" : "627726",
  "total": 20.30,
  "date" : "2015-06-09 12:00:00",
  "customer_id": "CUST-12ATCVWV",
  "customer_name": "Max Mustermann"
}

관계 모델링

관계는 종종 하위 자원에 의해 모델링됩니다. 하위 리소스의 경우 다음 패턴을 사용합니다.

GET  /{resource}/{resource-id}/{sub-resource}
GET  /{resource}/{resource-id}/{sub-resource}/{sub-resource-id}
POST /{resource}/{resource-id}/{sub-resource}

하위 리소스는 언제 사용하는가?

존재 의존적일 때

하위 개체가 상위 개체에 종속되어 있는 1:N 관계의 경우 하위 리소스를 사용합니다. "존재 의존적"은 하위 개체가 상위 개체 없이 존재할 수 없음을 의미합니다. 이러한 관계의 예로는 송장의 품목이 있습니다.

GET  /invoices/INV-567A89HG1/lineitems
POST /invoices/INV-567A89HG1/lineitems

관계에 속함

"Belongs to" 관계가 있는 경우 하위 리소스를 사용합니다.

송장은 고객의 것입니다. 모든 송장을 특정 고객에게 전달하거나 해당 고객에 대한 새 송장을 만들려면 GET 또는 POST를 수행합니다.

GET  /customers/CUST-12ATCVWV/invoices
POST /customers/CUST-12ATCVWV/invoices

다른 샘플로는 "개는 주인 소유", "셔츠는 사람의 소유" 등이 있습니다.

N:M 관계

N:M 관계의 경우 하위 리소스를 사용합니다. 하위 리소스는 처음에 가장 자주 따라야 하는 조회 방향을 지원하도록 정의할 수 있습니다. 양쪽 관계를 자주 쿼리해야 하는 경우 연결된 각 개체에 하나씩 두 개의 하위 리소스를 정의할 수 있습니다.

좋은 예로는 카풀로 N개의 운전자와 M개의 자동차가 있습니다.

GET /cars/CAR-3767FSHS/drivers
GET /drivers/DRI-ZU99983/cars

하위 리소스 대신 쿼리 매개 변수 사용

다른 유효한 옵션은 "Belongs to" 및 N:M 관계의 경우 하위 리소스 대신 쿼리 매개 변수를 사용하는 것입니다.

GET  /invoices?customer_id=CUST-12ATCVWV
POST /invoices

GET /drivers?car_id=CAR-3767FSHS
GET /cars?driver_id=DRI-ZU99983

API를 설계하는 방법을 일관되게 유지하는 것이 중요합니다.

0개의 댓글