REST API 리소스: 완벽 가이드

Iroro Chadere

Iroro Chadere

3 August 2025

REST API 리소스: 완벽 가이드

현대 웹 개발에서, Representational State Transfer (REST) API는 확장 가능하고 유지보수하기 쉬우며 이해하기 쉬운 웹 서비스를 구축하기 위한 사실상의 표준이 되었습니다. 모든 RESTful API의 핵심에는 근본적인 개념인 리소스가 있습니다. 리소스가 무엇인지, 어떻게 식별되는지, 그리고 우리가 리소스와 어떻게 상호작용하는지를 이해하는 것은 REST API를 효과적으로 설계하고 사용하는 데 가장 중요합니다. 이 글에서는 REST API에서 리소스의 본질을 깊이 탐구하며, 그 특성, 컬렉션과의 관계, 그리고 리소스에 대해 수행되는 일반적인 작업에 대해 살펴보겠습니다.

REST의 핵심 아이디어는 API가 일련의 리소스를 노출하고, 클라이언트는 고유 식별자로 요청을 전송하여 이러한 리소스와 상호작용한다는 것입니다. 하지만 정확히 무엇이 "리소스"를 구성할까요? REST API의 맥락에서 리소스는 이름을 붙일 수 있는 거의 모든 것이 될 수 있습니다. 고객, 제품 또는 주문과 같은 유형의 엔티티일 수도 있습니다. 서비스, 트랜잭션 또는 계산과 같은 추상적인 개념일 수도 있습니다. 핵심은 식별하고 조작할 수 있는 관심 대상이라는 것입니다.

인터넷 자체를 방대한 리소스 컬렉션으로 생각해보세요. 온라인에서 접근하는 모든 웹 페이지, 이미지, 비디오 또는 문서는 고유한 주소(URL)를 가진 리소스입니다. REST API는 이와 동일한 철학을 채택합니다. 소셜 미디어 플랫폼의 사용자 프로필이든, 온라인 도서관의 특정 책이든, 특정 도시의 일기 예보든, 각각은 API가 제공하는 리소스입니다.

💡
멋진 API 문서를 생성하는 훌륭한 API 테스트 도구를 원하십니까?

개발팀이 최고의 생산성으로 함께 작업할 수 있는 통합 올인원 플랫폼을 원하십니까?

Apidog는 귀하의 모든 요구를 충족하며, 훨씬 더 저렴한 가격으로 Postman을 대체합니다!
button

리소스 식별: URI의 역할

결정적으로, REST API의 모든 리소스는 하나 이상의 고유 식별자를 가져야 합니다. 이 식별자는 일반적으로 Uniform Resource Identifier (URI)입니다. 웹 API에서 사용되는 가장 일반적인 형태의 URI는 Uniform Resource Locator (URL)로, 이는 리소스를 식별할 뿐만 아니라 리소스를 찾는 수단도 제공합니다.

예를 들어, 블로그 관리를 위한 API에서 특정 블로그 게시물은 /posts/123과 같은 URI로 식별될 수 있습니다. 여기서 /posts는 게시물 컬렉션을 나타내고, 123은 해당 컬렉션 내 특정 게시물의 고유 식별자입니다. 마찬가지로 사용자 리소스는 /users/john.doe로 식별될 수 있습니다.

이러한 URI의 설계는 API 설계의 중요한 측면입니다. 잘 설계된 URI는 직관적이고 예측 가능하며 개발자가 이해하고 사용하기 쉽습니다. 접근하는 리소스의 특성을 나타내는 명확한 표지판 역할을 해야 합니다. 좋은 관행은 동사(예: /getProducts, /createOrder) 대신 명사(예: /products, /orders)를 사용하여 리소스를 나타내는 것입니다. 그런 다음 HTTP 메서드(GET, POST, PUT, DELETE)를 사용하여 URI로 식별된 리소스에 대해 수행할 작업을 지정합니다.

리소스 대 표현: 핵심적인 구분

리소스와 그 표현의 차이를 이해하는 것이 중요합니다. 리소스는 개념적 엔티티 자체입니다. 즉, 실제 "것"(고객, 제품, 아이디어)입니다. 반면에 표현은 특정 시점의 리소스 상태의 스냅샷이며, 일반적으로 JSON (JavaScript Object Notation) 또는 XML (eXetensible Markup Language)과 같은 특정 미디어 타입으로 형식이 지정됩니다.

클라이언트가 API에서 리소스를 요청할 때, 리소스 자체(서버에 상주하는 추상적인 개념)를 받는 것이 아닙니다. 대신 해당 리소스의 표현을 받습니다. 예를 들어, /users/jane.doe를 요청하면 API는 다음과 같은 JSON 표현을 반환할 수 있습니다.JSON

{
  "id": "jane.doe",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "dateJoined": "2023-01-15T10:00:00Z"
}

이 JSON 객체는 제인 도(Jane Doe) 본인이 아니라, 시스템에 저장된 그녀의 데이터 표현입니다. 동일한 리소스는 여러 표현을 가질 수 있습니다. 예를 들어, 클라이언트가 콘텐츠 협상(Accept와 같은 HTTP 헤더 사용)을 통해 요청하면 API는 동일한 사용자에 대한 XML 표현을 제공할 수도 있습니다.

리소스의 상태는 시간이 지남에 따라 변경될 수 있습니다. 제인 도가 이메일 주소를 업데이트하면 기본 사용자 리소스가 변경됩니다. 이후 /users/jane.doe에 대한 요청은 이 업데이트된 상태를 반영하는 새로운 표현을 반환합니다. 이것이 REST의 "상태 전송(State Transfer)" 부분이 작용하는 곳입니다. 클라이언트는 이러한 표현을 통해 리소스의 상태를 검색하고 조작하여 리소스와 상호작용합니다.

컬렉션: 다른 리소스를 포함하는 리소스

종종 리소스는 컬렉션으로 함께 그룹화됩니다. 컬렉션 자체도 리소스입니다. 예를 들어, 블로그 API의 /posts는 개별 게시물 리소스를 포함하는 컬렉션 리소스입니다. 마찬가지로 /users는 사용자 리소스의 컬렉션이 될 것입니다.

클라이언트가 /products와 같은 컬렉션 URI에 GET 요청을 보내면, API는 일반적으로 해당 컬렉션 내의 멤버 리소스를 나열하는 표현을 반환하며, 각 리소스에 대한 요약 정보도 포함하는 경우가 많습니다. 이 목록은 다음과 같을 수 있습니다.JSON

[
  {
    "id": "prod_abc",
    "name": "Laptop Pro 15",
    "price": 1299.99,
    "link": "/products/prod_abc"
  },
  {
    "id": "prod_xyz",
    "name": "Wireless Mouse Ergonomic",
    "price": 39.99,
    "link": "/products/prod_xyz"
  },
  // ... more products
]

컬렉션의 각 항목에 개별 리소스에 대한 링크(또는 자체 URI)가 포함되어 있어, 필요한 경우 클라이언트가 특정 제품의 전체 세부 정보를 탐색하고 검색할 수 있도록 하는 방식에 주목하세요.

컬렉션 및 해당 멤버에 대한 URI 설계는 논리적인 패턴을 따릅니다. 일반적으로:

이 계층적 구조는 API를 직관적으로 만들고 컬렉션과 해당 요소 간의 개념적 관계와 일치시킵니다.

리소스 및 컬렉션에 대한 작업

REST API에서 리소스 및 컬렉션과의 상호작용은 표준 HTTP 메서드를 통해 이루어집니다. 이러한 메서드는 수행할 작업을 정의합니다. 가장 일반적인 메서드는 다음과 같습니다.

GET: 리소스 또는 컬렉션의 표현을 검색하는 데 사용됩니다.

POST: 주로 컬렉션 내에 새 리소스를 생성하는 데 사용됩니다. 요청 본문에는 일반적으로 생성될 새 리소스의 표현이 포함됩니다.

PUT: 기존 리소스를 완전히 업데이트하는 데 사용됩니다. 요청 본문에는 리소스의 전체 새 표현이 포함되어야 합니다. URI로 식별된 리소스가 존재하면 새 표현으로 대체됩니다. 존재하지 않는 경우 일부 API는 이를 생성하도록 선택할 수 있습니다(이 동작은 다를 수 있습니다).

DELETE: 리소스를 제거하는 데 사용됩니다.

PATCH: 기존 리소스를 부분적으로 업데이트하는 데 사용됩니다. 리소스의 전체 표현을 보내야 하는 PUT과 달리 PATCH는 변경 사항만 보낼 수 있습니다. 예를 들어, 사용자의 이메일 주소만 업데이트하려면 PATCH 요청에 새 이메일만 포함하면 됩니다.

싱글톤 리소스

컬렉션과 그 멤버가 일반적이지만, 때로는 리소스가 독립적인 엔티티인 경우가 있으며, 이를 "싱글톤" 리소스라고 부르기도 합니다. 좋은 예로는 특정 애플리케이션의 구성이나 시스템의 현재 상태가 있습니다.

예를 들어, /application/configuration은 애플리케이션의 구성 설정을 나타내는 싱글톤 리소스의 URI가 될 수 있습니다. 이 URI에 대한 GET 요청은 현재 구성을 검색하고, PUT 요청은 이를 업데이트하는 데 사용될 수 있습니다. 이 맥락에서 구성의 "컬렉션"은 없으며, 그냥 구성만 있습니다.

마찬가지로 /system/status는 시스템의 현재 운영 상태를 나타낼 수 있습니다.

리소스 기반 API 설계를 위한 모범 사례

리소스 중심 API를 설계하는 것은 단순히 엔티티를 식별하고 URI에 매핑하는 것 이상을 포함합니다. 몇 가지 모범 사례는 강력하고 사용자 친화적인 API를 만드는 데 기여합니다.

  1. URI에 명사 사용: 앞서 언급했듯이, 리소스 URI는 명사여야 합니다(예: /products, /users/{userId}/orders). 동사는 HTTP 메서드를 위해 남겨두어야 합니다.
  2. 일관된 URI 명명: URI에 대해 일관된 명명 규칙을 사용하십시오. 일반적으로 컬렉션에는 복수 명사(예: /customer 대신 /customers)가 선호됩니다. 긴 경로 세그먼트의 가독성을 높이기 위해 밑줄(_)이나 카멜케이스 대신 하이픈(-)을 사용하십시오(예: /product-categories).
  3. URI를 단순하고 계층적으로 유지: 리소스 간의 관계를 반영하는 URI를 설계하십시오. 예를 들어, /users/{userId}/accounts/{accountId}는 계정이 사용자에게 속해 있음을 명확하게 보여줍니다. 그러나 URI를 다루기 어렵게 만들 수 있는 지나치게 깊은 중첩은 피하십시오.
  4. 무상태성: 클라이언트에서 서버로 보내는 각 요청은 요청을 이해하고 처리하는 데 필요한 모든 정보를 포함해야 합니다1. 서버2는 요청 간에 클라이언트 컨텍스트를 저장해서는 안 됩니다. 이것은 REST의 핵심 원칙이며 확장성에 기여합니다.
  5. HTTP 메서드를 올바르게 활용: GET, POST, PUT, DELETE, PATCH를 정의된 의미에 따라 사용하십시오. GET이 적절할 때 데이터를 수정하기 위해 GET을 사용하거나 데이터를 검색하기 위해 POST를 사용하지 마십시오.
  6. HTTP 상태 코드를 적절하게 사용: 요청의 결과를 나타내기 위해 표준 HTTP 상태 코드를 반환하십시오(예: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden,3 404 Not Found, 500 Internal Server Error). 이는 클라이언트에게 명확한 피드백을 제공합니다.
  7. 콘텐츠 협상 지원: 클라이언트가 Accept 헤더를 사용하여 원하는 표현 형식(예: JSON, XML)을 지정하고, Content-Type 헤더를 사용하여 요청 본문의 형식을 나타낼 수 있도록 허용하십시오.
  8. 버전 관리: 버전 관리 전략(예: /v1/products)을 구현하여 API 발전에 대비하십시오. 이를 통해 기존 클라이언트에 영향을 주지 않고 호환되지 않는 변경 사항을 도입할 수 있습니다.
  9. 의미 있는 오류 표현 제공: 오류가 발생하면 응답 본문(일반적으로 JSON 또는 XML)에 무엇이 잘못되었는지 설명하는 유용한 오류 메시지를 반환하십시오.
  10. 애플리케이션 상태 엔진으로서의 하이퍼미디어 (HATEOAS): 항상 완전히 구현되는 것은 아니지만, HATEOAS는 REST의 핵심 원칙입니다. 이는 리소스의 표현에 클라이언트가 관련 작업 및 리소스를 발견할 수 있도록 하는 링크(하이퍼미디어 컨트롤)가 포함되어야 함을 의미합니다. 예를 들어, 주문의 표현에는 주문 취소, 배송 상태 보기 또는 포함된 제품 보기 링크가 포함될 수 있습니다. 이는 API를 더 자체 발견 가능하게 만듭니다.

리소스의 세분성

일반적인 설계 과제 중 하나는 리소스의 적절한 세분성을 결정하는 것입니다. 주소는 별도의 리소스여야 할까요, 아니면 사용자 리소스의 일부여야 할까요? 주문 항목은 별개의 리소스여야 할까요, 아니면 주문 리소스 내에 포함되어야 할까요?

단 하나의 정답은 없습니다. 이는 특정 사용 사례와 클라이언트가 일반적으로 데이터와 상호작용하는 방식에 따라 달라집니다.

선택에는 종종 절충이 따릅니다.

이러한 요소를 신중하게 고려하고 API가 어떻게 사용될지에 대한 깊은 이해를 바탕으로 리소스 세분성에 대한 올바른 결정을 내리는 것이 중요합니다.

💡
멋진 API 문서를 생성하는 훌륭한 API 테스트 도구를 원하십니까?

개발팀이 최고의 생산성으로 함께 작업할 수 있는 통합 올인원 플랫폼을 원하십니까?

Apidog는 귀하의 모든 요구를 충족하며, 훨씬 더 저렴한 가격으로 Postman을 대체합니다!
button

결론

리소스는 모든 RESTful API의 기본 구성 요소입니다. 리소스는 API가 노출하고 클라이언트가 상호작용할 수 있는 "것들"을 나타냅니다. 리소스에 고유한 URI를 할당하고, 리소스와 그 표현을 구분하며, 리소스를 논리적인 컬렉션으로 구성함으로써 개발자는 직관적이고 확장 가능하며 REST 원칙을 준수하는 API를 만들 수 있습니다.

표준 HTTP 메서드를 사용하여 리소스를 정의, 식별 및 조작하는 방법을 이해하는 것은 API 설계자와 소비자 모두에게 필수적입니다. URI 설계 모범 사례, HTTP 상태 코드의 적절한 사용, 그리고 리소스 세분성에 대한 사려 깊은 접근 방식과 결합된 잘 정의된 리소스 모델은 기능적일 뿐만 아니라 함께 작업하기에도 즐거운 API로 이어집니다. 디지털 환경이 계속 발전함에 따라 리소스 중심 아키텍처의 원칙은 효과적인 웹 서비스 통신의 초석으로 남을 것입니다.

Apidog에서 API 설계-첫 번째 연습

API를 더 쉽게 구축하고 사용하는 방법을 발견하세요