Server

RESTful API 디자인 마스터하기: 실용적인 가이드

범데이 2025. 2. 23. 23:22

오늘은 dev.to 사이트에서 RESTful API 디자인 관련 유용한 포스팅이 있어서, 직접 한글로 번역하여 포스팅하게 되었다.

[원본 포스팅: https://dev.to/leapcell/mastering-restful-api-design-a-practical-guide-408]


RESTful API(Representational State Transfer API)는 네트워크 애플리케이션 간 상호작용에 사용되는 네트워크 인터페이스 디자인 스타일이다. REST는 특정한 표준이나 프로토콜이 아니라, 아키텍처 원칙과 제약 조건의 집합이다.

웹 서비스가 "RESTful" 일 때 REST원칙을 따르고 효율적이고 안정적이며 확장 가능한 네트워크 서비스를 제공한다.

 

RESTful 서비스에서 각 요청는 요청을 처리하는데 필요한 모든 정보를 포함해야 한다. 서버는 클라이언트 요청에 대한 상태 정보를 보관해서는 안된다.

 

RESTful 아키텍처는 여러 계층으로 구성될 수 있으며, 각각은 특정 기능을 수행한다. 이 구조는 더 복잡하고 강력한 애플리케이션을 개발할 수 있게 한다.

 

 

 

URL 디자인

RESTful API에서 URL(Uniform Resource Locator)은 일반적으로 리소스(객체)를 나타내며, HTTP메서드(GET, POST, PUT, DELETE 등)는 해당 리소스에 대한 작업(동사)를 나타낸다. 즉, RESTful API는 리소스의 상태와 표현을 강조하며, 명령어 기반이 아니라 리소스 중심으로 설계된다.

 

 

동사 + 목적어

RESTful API에서 사용되는 주요 HTTP메서드는 다음과 같이 CRUD(Create, Read, Update, Delete)연산과 연결된다.

- GET: 조회

- POST: 생성

- PUT: 업데이트

- PATCH: 업데이트 (일반적으로 부분 업데이트용)

- DELETE: 삭제

 

 

목적어는 명사여야 한다.

RESTful 설계 원칙에 따르면 URL은 명사(리소스)를 표현해야 하며, 동사를 포함해서는 안된다.

왜냐하면 URL은 액션이 아닌 "리소스" 컬렉션이나 단일 인스턴스를 나타내기 때문이다.

 

 

잘못된 예:

- /getAllCars

- /createNewCar

- /deleteAllRedCars

 

이러한 URL에는 리소스 자체가 아니라 동작을 설명하는 동사(예: get, create, delete)가 포함된다. 이 디자인은 RESTful 의미론적 표준을 따르지 않는다.

 

올바른 예:

- /users → 사용자의 컬렉션을 나타낸다.

- /users/123 → 특정 ID(123)를 가진 단일 사용자를 나타낸다.

 

위의 예에서 /users 및 /users/123 는 모두 명사로, 각각 사용자 컬렉션과 특정 사용자 리소스를 나타낸다. 이러한 URL 디자인은 API를 이해하기 쉽게 만들고 RESTful 리소스 지향 원칙과 일치한다.

 

이 명명 규칙을 따르면 API 경로가 명확하고, 일관되며, 이해하고 유지 관리하기 쉬워진다.

 

 

복수형 URL

URL은 일관성을 유지하기 위해 복수형을 사용하는 것이 일반적이다.

(이는 URL이 일반적으로 리소스 모음을 나타내기 때문이다.)

 

URL이 리소스 모음을 가리키는 경우 복수형 명사를 사용한다. 예를 들어, 모든 사용자 모음을 나타내려면 /user 대신 /users 를 사용한다.

 

단일 리소스를 가리키는 경우에도 복수형을 사용하는 것이 좋다. 예를 들어, /users/123 는 ID가 123인 사용자를 나타낸다. 이 접근 방식은 URL 일관성을 유지한다.

 

리소스에 계층적 관계가 있는 경우 URL은 이 구조를 반영해야 한다. 예를 들어, /users/123/posts/는 사용자 123에 대한 게시물 모음을 나타낼 수 있다.

 

 

너무 깊은 중첩 피하기

너무 깊은 URL 구조는 가독성을 떨어트릴 수 있으므로 피하는 것이 좋다.

 

- 비효율적인 예: /authors/12/categories/2

이러한 URL은 확장하기 어렵고 의미론이 불분명하여 이해하기 위해 추가적인 노력이 필요한 경우가 많다.

 

- 더 나은 방식: /authors/12?categories=2

더 나은 접근 방식은 첫 번째 수준을 넘어서는 쿼리 매개변수를 사용하는 것이다.

 

상태 코드

API 서버는 요청에 대한 응답으로 적절한 HTTP 상태 코드를 반환해야 한다.

 

HTTP 상태 코드는 5가지 범주로 구분된 3자리 숫자이다.

 

- 1xx: 정보

- 2xx: 성공

- 3xx: 리디렉션

- 4xx: 클라이언트 오류

- 5xx: 서버 오류

 

이 5가지 범주에는 가능한 대부분의 상황을 포괄하는 100개 이상의 상태 코드가 포함되어 있다. 각 상태 코드에는 표준(또는 관례적으로 수용되는) 의미가 있어 클라이언트가 상태 코드만 확인하면 무슨 일이 일어났는지 판단할 수 있다. 따라서 서버는 가능한 가장 정확한 상태 코드를 반환해야 한다.

 

API에는 1xx 상태 코드가 필요하지 않는다. 아래는 다른 네 가지 범주에 대한 설명이다.

 

 

2xx 상태 코드

다양한 HTTP 요청 방법은 요청 결과를 나타내기 위해 해당 상태 코드를 반환해야 한다. 200 OK 는 일반적인 성공 응답이지만, 방법에 따라 더 정확한 상태 코드를 사용해야 한다.

  • GET: 200 OK – 요청이 성공했고 리소스가 반환되었다.
  • POST: 201 Created – 새로운 리소스가 성공적으로 생성되었으며, 응답에는 일반적으로 리소스의 URI가 포함된다.
  • PUT: 200 OK 또는 204 No Content – ​​전체 리소스 업데이트에 사용됨. 콘텐츠가 반환되면 200을 사용하고, 그렇지 않으면 204를 사용함 .
  • PATCH: 200 OK 또는 204 No Content – PUT과 유사하게 부분 업데이트에 사용된다. 204는 콘텐츠가 반환되지 않았음을 나타낸다.
  • DELETE: 204 No Content – 리소스가 성공적으로 삭제되었음을 나타내며 일반적으로 응답에 내용이 없다.
  • 202 Accepted – 요청이 승인되었지만 아직 처리되지 않았다. 비동기 작업에 유용하다.
  • 206 Partial Content – 클라이언트가 Range 헤더를 사용하여 대용량 파일의 일부를 요청할 때 일반적으로 사용되는 부분 응답을 나타낸다.

 

3xx 상태 코드

API는 일반적으로 301(영구 리디렉션) 또는 302(임시 리디렉션, 307 포함)를 사용하지 않는다. 이는 대부분 브라우저 수준 탐색과 관련이 있기 때문이다. 대신 API는 애플리케이션 수준에서 이러한 시나리오를 처리할 수 있다.

 

그러나 API는 다른 URL을 참조하는 303 See Other를 사용할 수 있다. 302  307 과 마찬가지로 "임시 리디렉션"을 의미하지만 303은 POST, PUT 및 DELETE 요청 에 특별히 사용된다 . 302 와 달리 브라우저는 303 리디렉션을 자동으로 따르지 않고 대신 사용자가 다음 단계를 결정하도록 허용한다.

 

응답 예시:

HTTP/1.1 303 See Other
Location: /api/orders/12345
 
 

4xx 상태 코드

4xx 상태 코드는 클라이언트 오류를 ​​나타낸다. 일반적인 오류는 다음과 같다.

  • 400 Bad Request – 서버가 클라이언트의 요청을 이해하지 못하고 처리하지 않는다.
  • 401 Unauthorized – 사용자가 인증 자격 증명을 제공하지 않았거나 인증에 실패했다.
  • 403 Forbidden – 사용자가 성공적으로 인증되었지만 리소스에 액세스할 수 있는 권한이 없다.
  • 404 Not Found – 요청한 리소스가 존재하지 않거나 사용할 수 없다.
  • 405 Method Not Allowed – 사용자가 성공적으로 인증되었지만 허용되지 않는 HTTP 메서드를 사용하고 있다.
  • 410 Gone – 요청된 리소스가 영구적으로 제거되었다.
  • 415 Unsupported Media Type – 요청한 형식이 지원되지 않는다. 예를 들어, API가 JSON만 반환하지만 클라이언트가 XML을 요청하는 경우 이 상태가 반환되어야 한다.
  • 422 Unprocessable Entity – 클라이언트가 처리할 수 없는 첨부 파일을 제공했기 때문에 요청이 실패했다.
  • 429 Too Many Requests. 클라이언트가 허용된 요청 수를 초과했다.

 

5xx 상태 코드

5xx 상태 코드는 서버 오류를 나타낸다. API는 일반적으로 사용자에게 내부 서버 세부 정보를 노출하지 않으므로 일반적으로 두 가지 상태 코드만 사용된다.

  • 500 Internal Server Error – 클라이언트 요청은 유효했지만 서버에서 처리하는 동안 예상치 못한 문제가 발생했다.
  • 503 Service Unavailable – 서버가 일시적으로 요청을 처리할 수 없으며, 이는 종종 유지 관리 기간에 사용된다.

 

 

서버 응답

API 응답은 일반 텍스트가 아니라 구조화된 JSON 객체여야 표준 형식을 보장할 수 있다. 서버의 Content-Type헤더는 application/json 으로 설정해야 한다.

 

클라이언트는 요청에서 Accept 헤더를 설정하여 JSON 응답을 허용한다는 점도 지정해야 한다.

GET /orders/2 HTTP/1.1
Accept: application/json

 

콘텐츠 반환 정책

 POST요청의 경우, 응답으로 생성된 리소스를 포함할지 여부는 구현에 따라 다를 수 있다.

 

리소스를 반환하는 방식

HTTP/1.1 201 Created
Location: /resources/123
Content-Type: application/json
{
  "id": 123,
  "name": "New Resource"
}

이 접근 방식에는 201 Created 상태 코드와 응답에 새 리소스의 전체 세부 정보가 포함된다.

또한 리소스의 URL를 가리키는 Location 헤더도 포함된다.

 

 

리소스 반환 없이 응답하는 방식

HTTP/1.1 201 Created
Location: /resources/123

위와 같이 리소스 세부 정보를 생략하고 Location 헤더와 함께 201 Created 또는 204 No Content 응답만 반환하도록 선택할 수 있다. 이렇게 하면 데이터 전송이 최소화되고 클라이언트가 나중에 리소스를 검색할지 여부를 결정할 수 있다.

 

 

 

결론

RESTful API는 HTTP 프로토콜을 기반으로 리소스 중심의 설계를 따르며, 상태 정보를 저장하지 않는 특성을 가진다.

올바른 HTTP 메서드 사용, 직관적인 URL 설계, 적절한 상태 코드 반환, 일관된 JSON 응답을 통해 확장 가능하고 유지보수가 용이한 API를 만들 수 있다.

728x90
반응형