RESTful API 가이드라인

2024. 11. 18. 01:52·정리 및 생각

RESTful API란 무엇일까? 약자 그대로 Representational State Transfer-ful API. 즉 REST 아키텍처 스타일을 잘 준수하는 API를 의미한다. 개발 프로세스의 핵심 단계인 API 명세서를 작성하기에 앞서, REST의 제약 조건에 대해 간단히 알아본 후에 RESTful한 API를 설계하고 구현할 때 고려해야 할 가이드라인을 정리해보려고 한다. 

 

최근 업데이트: 2024-11-17

 

REST 아키텍처의 제약 조건

- 클라이언트/서버 구조

클라이언트와 서버는 인터페이스를 통해 서로 명확하게 분리되어야 한다. 클라이언트는 프론트엔드 측에서 구현하고, 리소스를 제공하는 서버는 백엔드 측에서 구현한다. REST API는 서버와 클라이언트를 이어주는 인터페이스가 된다.

 

- 무상태(Stateless)

서버 애플리케이션은 클라이언트의 요청과 관련된 데이터를 저장하지 않는다. 즉, 클라이언트의 각 요청에는 처리에 필요한 모든 정보가 포함되어야 한다. Session 정보의 필요가 없어지고, 효율적인 부하 분산과 확장이 가능하다.

 

- 캐시 가능성(Cache)

클라이언트나 서버 측에서 리소스를 캐시할 수 있어야 한다. Cache-control 헤더나 GET method 등을 통해 HTTP 캐시를 구현할 수 있다. 캐시를 통해 불필요한 요청을 줄여 네트워크 효율성을 향상시킨다.

 

- 계층형 구조(Layered system)

REST API에서 요청과 응답은 여러 중간 계층(캐싱 서버, 프록시 서버, 로드 밸런서, 인증 계층 등)을 거친다. REST API는 클라이언트나 서버 측에서 중간 계층에 대해서 모르도록 설계함으로써 중간 계층의 확장성과 보안을 높일 수 있다.

 

- 인터페이스 일관성(Uniform interface)

  1. 모든 리소스는 고유한 URI로 식별되어야 한다.
  2. 리소스는 표현(JSON, XML 등의 포맷) 형태로 전달되어야 한다. 표현과 리소스는 구분된다.
  3. 요청과 응답에는 의미와 처리 방법 등 필요한 모든 정보를 자체적으로 포함해야 한다.
  4. HATEOAS(Hypermedia As The Engine Of Application State): Hypermedia를 통해서 상태 전이가 가능해야 한다. 서버가 응답 메시지에 현재 리소스와 관련 리소스에 대한 '링크'를 포함함으로써, 클라이언트가 해당 링크를 따라 리소스를 탐색할 수 있도록 하는 것이다. 클라이언트는 응답에 대한 사전지식 없이도 서버와의 상호작용이 가능하다.

 

Richardson Maturity Model에서는, HATEOAS까지 구현한 REST API를 가장 성숙한 maturity level 3의 API라고 한다. 하지만 일반적인 조직 내 개발에서는 협업만으로 충분히 URI 구조의 관리가 가능하고, Open API라도 명세서 문서화가 잘 갖추어져 있다면 굳이 하이퍼미디어를 제공할 필요가 있는지 의문이 든다. '클라이언트 측의 편의성'과 'HATEOAS 구현의 효율'을 따져보아도 더 친절하고 자세한 API 명세서를 만드는 데 시간을 들이는 것이 낫다는 생각이 든다.


RESTful API 가이드라인

그렇다면 RESTful한 API를 설계하려면 어떤 사항들을 고려해야 할까? 일관성 있는 API 설계를 위해 가이드라인을 정리해보고자 한다. 주로 마이크로소프트 아쥴에서 작성된 글을 참조하였고, 기본적이고 중요한 내용 위주로 정리하였다.

 

I. HTTP 기본 사항

1. HTTP 메서드

  • GET: 지정된 URI에서 리소스를 요청한다. 요청의 body를 사용하지 않는다.
  • POST: 지정된 URI에 새 리소스를 만든다. 주로 컬렉션(`/users`)으로 요청한다.
  • PUT: 지정된 URI에 리소스를 만들거나 기존 리소스를 업데이트한다. 즉 URI를 사용하는 리소스가 이미 있으면 새 리소스로 대체된다. 요청에는 리소스의 완전한 표현이 들어있다. 주로 고유 URI (`/users/99`)로 요청한다.
  • PATCH: 지정된 URI의 리소스를 부분적으로 업데이트한다. 요청에는 리소스의 변경 내용만이 들어있다.
  • DELETE: 지정된 URI의 리소스를 제거한다.

 

2. 멱등성 (idempotent)

GET, HEAD, PUT, DELETE는 멱등성을 가져야 한다. 즉 여러 번의 동일한 요청이 반복되어도 결과는 동일하여야 한다. (상태 코드는 달라질 수 있다)

POST, PATCH는 멱등성을 가지지 않을 수 있다.

 

3. 주로 사용되는 HTTP 상태 코드

  • 2xx Success✅
    • 200 OK: 요청이 성공적으로 처리되었다. 여러 메서드에 범용적으로 사용된다.
    • 201 Created: 요청이 처리되어 새로운 리소스가 생성되었다.
    • 204 No Content: 요청이 처리되었지만 반환할 데이터가 없다. 주로 DELETE 성공 시 반환된다.
  • 3xx Redirection
    • 301 Moved Permanently: 요청한 리소스의 URL이 영구적으로 변경되었다. 변경된 URL로 자동으로 이동한다.
    • 304 Not Modified: 클라이언트가 캐싱된 리소스를 요청했지만, 서버의 리소스가 변경되지 않았다. 기존 캐시 데이터를 사용한다.
  • 4xx Client Error
    • 400 Bad Request: 잘못된 파라미터나 형식 오류 등으로 요청이 잘못되었다.
    • 401 Unauthorized: 리소스에 인증이 필요하지만 인증 정보가 제공되지 않았거나 잘못된 인증 정보가 제공되었다.
    • 403 Forbidden: 클라이언트에게 리소스 접근 권한이 없다. 리소스에 대한 엑세스가 금지되었다.
    • 404 Not Found: 요청한 리소스를 찾을 수 없다.
    • 405 Method Not Allowed: 요청에 사용된 HTTP 메서드가 지원되지 않는다.
    • 429 Too Many Requests: 클라이언트가 일정 시간 내에 너무 많은 요청을 보냈다.
  • 5xx Server Error
    • 500 Internal Server Error: 서버에서 요청을 처리하는 중에 예상치 못한 오류가 발생했다.
    • 501 Not Implemented: 서버가 요청한 URI의 메서드에 대해서 구현하고 있지 않다.
    • 502 Bad Gateway: 게이트웨이 또는 프록시 역할을 하는 서버가 다른 서버로부터 잘못된 응답을 받았다.

 

II. API 디자인과 구현

1. URI는 모두 소문자로, kebab-case를 사용한다. 언더스코어(_)는 지양한다.

 

2. URL에서 .html 등 파일 확장자는 생략한다.

 

3. 데이터베이스의 테이블명 등 데이터 항목은 URI에 드러나지 않도록 한다. 

 

4. 인증토큰은 URL이나 Body가 아닌 Header에 넣고, Token의 유효기간은 짧은 것이 보안상 좋다.

 

5. URI는 명사(리소스)를 기반으로 한다.

동사(리소스에 대한 작업)가 아닌 명사(리소스)를 기반으로 API 디자인을 구성해야 한다. 동사 역할은 HTTP Method가 한다. 

- Good
POST /orders
POST /session

- Avoid
POST /login
POST /create-order

 

6. 컬렉션

컬렉션과 컬렉션 내 항목(Item)을 별도로 구분하고, 고유한 URI를 갖도록 한다.

컬렉션을 참조하는 URI는 복수 명사를 사용한다. 

- Collection
https://example.com/orders

- Item
https://example.com/orders/1

 

7. 다른 리소스와의 연결

서로 다른 리소스 간의 연결은 다음과 같이 한다.

- 고객 5에 대한 모든 주문
/customers/5/orders

- 주문 99에 대한 모든 고객
/orders/99/customers

- Avoid (너무 많은 연결)
/customers/1/orders/99/products

 

주의) 너무 많은 관계가 연결된 URI는 복잡성을 유지하기 어렵고, 리소스 간의 관계가 변할 경우 유연하게 사용하기 어렵다. URI는 컬렉션/항목/컬렉션 정도까지의 복잡성이 적합하다.

 

8. 데이터 필터링

쿼리 파라미터를 이용하여 리소스에 대한 필터링, 정렬, 페이징을 구현한다. 파라미터 별 기본값을 정한다. 파라미터의 key와 value는 모두 camelCase로 한다.

  • 정렬: sort
  • 페이징: page, limit
  • 검색: search
  • 필드 선택: fields

파라미터 key와 value의 조건을 표현할 때는 적절한 접미사를 활용한다.

  • Lte: less than or equal (작거나 같음)
  • Gte: greater than or equal (크거나 같음)
  • Eq: equals (같음)
  • In: 포함된 값
  • Asc: ascending (오름차순)
  • Desc: descending (내림차순)
- 정렬
GET /products?sort=priceAsc

- 페이징
GET /users?page=2&limit=20

- 검색
GET /articles?search=climate+change

- 필드
GET /users?fields=id,name,email

- 예제
GET /products?category=books&priceLte=50&sort=priceAsc&page=1&limit=10
GET /users?role=admin&active=true&fields=id,name,email

 

9. Body

요청과 응답의 Body(본문)는 JSON 형식을 사용한다. JSON의 모든 데이터는 snake_case를 사용한다.

 

10. 응답 형식

- 응답은 `success`, `data`, `message`를 포함한다.

{
  "success": true,
  "data": {...},
  "message": "Resource retrieved successfully."
}

 

- 리스트 형식의 객체를 응답할 때에는 리스트의 개수를 포함하는 것이 좋다. 페이지 객체들을 응답할 때에는 페이징 정보(pagination)를 명시한다.

{
  "success": true,
  "data": [
    ...
  ],
  "pagination": {
    "totalItems": 50,
    "page": 1,
    "pageSize": 10,
    "totalPages": 5
  },
  "message": "Products retrieved successfully."
}

 

11. API Versioning

URI의 첫 번째 세그먼트로 버전을 명시한다. 버전의 번호는 처리의 편의를 위해 자연수로 한다.

/v1/users
/v2/products/1

 


 

잘 정립된 가이드라인과 컨벤션은 품질의 일관성을 유지시켜주고, 협업의 효율성을 상승시킨다. 앞으로 해 나갈 무수한 설계와 개발에 있어 이 가이드라인이 내 성장의 기반이 되었으면 좋겠다.

 

 

 

 

 

Reference)

웹 API 디자인 모범 사례 - Azure Architecture Center | Microsoft Learn

웹 API 구현 - Best practices for cloud applications | Microsoft Learn

데이터가 없을 때 200인가 404인가?. 오류가 아닌데 왜 4xx로 반환하는 거예요? | by Jinyoung Ko | YOGIYO Tech Blog - 요기요 기술블로그

Google JSON Style Guide

HATEOAS 실무에서 얼마나 사용하나요? - 인프런 | 커뮤니티 질문&답변

'정리 및 생각' 카테고리의 다른 글

남는 노트북으로 홈 서버 구축하기  (0) 2025.01.21
JWT 알아보기  (2) 2024.11.21
관계형 데이터베이스 네이밍 컨벤션 정리  (5) 2024.11.11
'정리 및 생각' 카테고리의 다른 글
  • 남는 노트북으로 홈 서버 구축하기
  • JWT 알아보기
  • 관계형 데이터베이스 네이밍 컨벤션 정리
j30ngwoo
j30ngwoo
  • j30ngwoo
    Jeongwoo Dev Blog
    j30ngwoo
  • 전체
    오늘
    어제
  • 글쓰기 관리
    • 분류 전체보기 (16)
      • 정리 및 생각 (4)
      • Problem Solving (2)
      • 해결 및 개선 (5)
      • Projects (3)
  • 인기 글

  • 태그

    티스토리챌린지
    오블완
    whenwhen
    kupc2023
    spring
    backend
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
j30ngwoo
RESTful API 가이드라인
상단으로

티스토리툴바