저번 포스트에서는 Http method에 대해서 알아보았는데요 🔗.
이번에는 Http method에서 배운 것을 바탕으로 Restful API Endpoint를 설계하는 것에 대해서 다루어보겠습니다.
📌 리소스를 식별해라
🤔 리소스란 무엇을 의미할까요?
REST에서 주요 데이터 표현은 자원(resource)이라고 합니다. 일관성 있고 강력한 REST 자원 이름 전략을 갖추는 것은 장기적으로 매우 중요한 설계 결정이 될 것입니다.
REST에서 정보의 핵심 추상화는 자원입니다. 이름을 지을 수 있는 모든 정보는 자원이 될 수 있습니다. 예를 들어, 문서나 이미지, 시간에 따라 변하는 서비스(예: "오늘의 로스앤젤레스 날씨"), 다른 자원들의 모음, 실제 물건(예: 사람) 등이 자원이 될 수 있습니다.
다시 말해, 하이퍼텍스트 참조의 대상이 될 수 있는 모든 개념은 자원의 정의에 부합해야 합니다.
자원은 특정 시점에 해당하는 엔티티가 아니라, 엔티티 집합에 대한 개념적 매핑입니다. 즉, 자원은 특정 엔티티나 데이터가 아닌 그 데이터가 속하는 집합을 나타내는 개념적인 구조라고 볼 수 있습니다.
— Roy Fielding’s dissertation
정의로 다가가면 조금 어려운 감이 있습니다.
예를 들어서 회원과 관련된 API 기능들을 다음과 같이 구현한다고 해보겠습니다.
- 회원 조회
- 회원 등록
- 회원 정보 수정
- 회원 삭제
- 회원의 계좌 조회
여기서 리소스는 회원입니다. 대상이 되는 명사가 리소스가 됩니다.
📌 리소스를 복수로 식별할 것
리소스는 Singleton(단수)가 될수도 있고 Collection(복수)가 될수도 있습니다.
하지만, 기본적으로 설계는 복수형태로 설계를 하도록 권고하고 있습니다.
대신 다음과 같이 Singleton과 Collection의 케이스를 나누고 있습니다.
/customers -> Collection(복수)를 표현합니다.
/customers/{id} -> 다음과 같은 방법으로 Singleton(단수)의 리소스에 접근하는 것을 표현합니다.
📌 리소스는 하위 리소스를 가질 수 있다
리소스는 계층 구조를 가질 수 있고 이에 따라서 하위 리소스를 가질 수도 있습니다.
/customers
/customers/{id}/accounts -> Account는 Customer아래에 들어가는 하위 리소스입니다.
📌 동사와 CRUD Operation명을 절대 Endpoint에 넣지 말 것
앞서서 리소스를 식별하라고 설명했는데요, 그렇다면 리소스에 대한 어떤 행위를 하는지 표현을 해주어야 합니다.
하지만,이 과정에서 URL에 동사를 넣지 않습니다(이런 설계는 Restful 설계가 아니라 RFC라고 합니다) .
대신, HttpMethod를 이용해서 어떤 행위를 하는지 규정해주는데요 !
리소스를 식별하고 그에 대한 행위는 Http Method를 사용하는 것이죠.
그렇기 때문에 Endpoint에 동사와 CRUD Operation명을 지양하라고 설명하고 있습니다!
앞서서 말했던 예시에 대한 Endpoint를 이제 완성해보겠습니다.
- 회원 조회 : GET /users/{id}
- 회원 등록 : POST /users
- 회원 정보 수정 : PATCH /users/{id}
- 회원 삭제 : DELETE /users/{id}
- 회원의 계좌 조회 : GET /users/{id}/account
✌🏻 다음과 같은 방법으로 Endpoint를 규정해줄 수 있습니다!
✅ 하지만, 이건 어디까지나 Best Practice일 뿐 실제로 프로젝트를 하는 과정에서는 Endpoint에 동사가 들어가게 되는 경우가 심심치 않게 발생할 수 있습니다.
여기까지가 핵심적인 부분이고 부수적인 조건들을 말씀드리면서 포스트를 마치겠습니다.
📌 리소스를 식별할 때에는 명사형을 사용할 것
예시 :
/device-management/managed-devices
/device-management/managed-devices/{device-id}
/user-management/users
/user-management/users/{id}
리소스를 식별하는 것을 기본으로 하고 명사형으로 식별하자.
📌 /(슬래시)는 앞에 넣어서 위계를 표현하자
http://api.example.com/device-management/managed-devices/
http://api.example.com/device-management/managed-devices <- 이게 더 좋습니다.
슬래시를 이용해서 위계를 표현하되 뒤에 붙이지는 말 것.
📌 (-)를 사용하여 가독성을 높이고 (_)를 쓰지 말자
http://api.example.com/devicemanagement/manageddevices/%20 <- 아무것도 없는 것은 가독성이 떨어집니다.
http://api.example.com/device_management/managed-devices%20 <- (_) 를 쓰면 조금 더 잘보이지만
http://api.example.com/device-management/managed-devices%20 <- (-) 를 쓰는 것을 권고합니다.
📌 소문자를 사용하여 url을 표현할 것
말 그대로 대문자를 사용하지 않으시면 됩니다.
📌 파일 확장자를 쓰지 말 것
/device-management/managed-devices.xml <- 사용하지 마세요!
/device-management/managed-devices <- 이게 맞습니다.
📌 쿼리 파라미터를 사용할 것
/device-management/managed-devices
/device-management/managed-devices?region=USA
/device-management/managed-devices?region=USA&brand=XYZ
/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date
쿼리 파라미터를 사용해서 결과를 필터링 하라고 설명하고 있습니다.
⭐ 단, 쿼리 파라미터는 Endpoint에 쓰지는 않습니다 !!!
-> API 명세서를 만든다면 기능에 설명해주세요.
Reference:
Best Practice 참고사항 - restfulapi.net 🔗
강의 - 모든 개발자를 위한 Http 기본 지식 (김영한) 🔗
'프로젝트' 카테고리의 다른 글
배포의 모든 것 - 2. RDS와 Session Manager (0) | 2025.02.25 |
---|---|
배포의 모든 것 - 1. AWS 시작하기 및 EC2 띄우기 (5) | 2025.01.25 |
DDD(Domain Driven Design) 구조 알아보기 (5) | 2025.01.14 |
API 응답 통일을 파헤치다 (0) | 2025.01.01 |
커스텀 상태 코드(Custom Error Code) (0) | 2025.01.01 |