REST API란?

쓰리원·2023년 2월 12일
0

Http

목록 보기
2/2
post-thumbnail

REST API 를 형태로 서버와 통신해서 원하는 DATA 를 CRUD(Create, Read, Update, Delete)하기 위해서 현업에서 수없이 많이 사용하고 있지만, 따로 지식 정리를 해본적은 없어서 막상 설명을 하자니 어려웠습니다. 이미 저와 같은 경험을 하신분들이 여러명 있더군요... 이번 기회에 정리를 해보려고 합니다.

1. REST API 란?

REST(Representational State Transfer)는 웹 서비스를 설계하는 데 사용되는 아키텍처 스타일입니다. REST는 인터넷에서 웹 서비스 간의 통신을 용이하게 하는 몇 가지 기본 원칙을 제시합니다. 이러한 원칙을 따르는 API를 REST API 또는 RESTful API라고 합니다.

좀 더 직접적으로 이해하기 쉽게 이야기 하면, Representational State Transfer : 자원의 표현으로 상태를 전달하는 것으로 URI로 자원을 표현하는 데에 집중하고, 자원의 상태(행위)에 대한 정의는 HTTP METHOD로 하는 것이 REST한 API를 설계하는 중심 규칙이라고 볼 수 있습니다.

1. REST API 구성

  • 자원(RESOURCE) - URI
  • 자원의 상태 : 행위 (Verb) - HTTP METHOD
  • 표현(Representations)

REST API 설계 시 가장 중요한 항목은 다음의 2가지로 요약할 수 있습니다.

첫 번째, URI는 정보의 자원을 표현해야 합니다.
두 번째, 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 정의해야 합니다.

2. REST API 구성의 예

  • 1) URI는 정보의 자원을 표현. (리소스명은 동사보다는 명사를 사용)
    GET /members/delete/1

위와 같은 방식은 REST를 제대로 적용하지 않은 URI입니다. URI는 자원을 표현하는데 중점을 두어야 합니다. delete와 같은 행위에 대한 표현이 들어가서는 안됩니다.

  • 2) 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE 등)로 표현.

위의 잘못 된 URI를 HTTP Method를 통해 수정해 보면

    DELETE /members/1

으로 수정할 수 있습니다. 회원정보를 가져올 때는 GET, 회원 추가 시의 행위를 표현하고자 할 때는 POST METHOD를 사용하여 표현합니다.

  • 3) 더 구체적으로 자원(Resource)의 표현(Represent)

자원(Resource)의 표현(Representation)은 클라이언트가 서버로부터 전송받은 데이터를 어떻게 해석하고 처리할지 결정합니다. 리소스를 표현하는 방식 중 document, collection, store, controller라는 네 가지 방식이 있습니다.

1. Document (문서): 개별적인 자원을 나타내는 단일 문서입니다. 예를 들어, 특정 제품의 상세 정보를 담은 웹 페이지가 이에 해당합니다.

http://restapi.example.com/products/1

이 URI에서 "products"는 컬렉션을 나타내며, "1"은 도큐먼트로서 특정 제품을 나타냅니다.

2. Collection (컬렉션): 유사한 자원의 집합을 나타내는 자원입니다. 예를 들어, 여러 제품 목록을 담은 웹 페이지가 이에 해당합니다.

http://restapi.example.com/products

이 URI에서 "products"는 제품 목록을 나타내는 컬렉션입니다.

3. Store (저장소): 클라이언트가 자원을 생성, 수정, 삭제할 수 있는 저장소를 나타냅니다.

http://restapi.example.com/users/1/posts

이 URI에서 "users"와 "posts"는 컬렉션을 나타내며, "1"는 도큐먼트로서 특정 사용자를 나타냅니다. 이 경우 사용자의 게시물을 생성, 수정, 삭제할 수 있는 저장소를 나타내는 것입니다.

4. Controller (컨트롤러): 자원에 대한 특정 작업을 수행하는 엔드포인트입니다. 일반적으로는 CRUD 작업 외의 추가적인 작업을 수행할 때 사용됩니다.

http://restapi.example.com/products/1/publish

이 URI에서 "products"는 컬렉션을 나타내며, "1"은 도큐먼트로서 특정 제품을 나타냅니다. publish는 제품에 대한 정보를 공개적으로 게시하거나 활성화하는 기능을 수행할 수 있습니다. 이러한 컨트롤러는 일반적으로 CRUD 작업 외의 추가 작업을 수행할 때 사용됩니다.

예를 들어, 관리자가 웹사이트에서 새로운 제품을 출시하려고 할 때, 해당 제품의 정보를 데이터베이스에 추가한 후 (이미 CRUD 작업을 통해 수행됨), publish 컨트롤러를 호출하여 제품을 공개하거나 활성화할 수 있습니다. 이렇게 함으로써, 제품이 사용자들에게 표시되고 구매할 수 있게 됩니다.

위에서 제공한 예제를 통해, document, collection, store, controller의 개념과 각각의 역할을 이해할 수 있습니다. RESTful API를 설계할 때 이러한 구조를 기반으로 자원을 구성하면 클라이언트와 서버 간의 상호 작용이 더 직관적이고 효율적이게 됩니다.

3. 주요 원칙 요약.

  • Uniform Interface
    균일한 인터페이스 원칙은 API 디자인에 일관성을 제공하며, 클라이언트와 서버 간의 통신을 단순화합니다. 이 원칙은 다음과 같은 하위 원칙으로 구성됩니다. 리소스 식별, 리소스 조작을 위한 표현, 메시지 자체 설명성, Hypermedia as the Engine of Application State (HATEOAS).

  • Stateless
    클라이언트와 서버 간의 모든 요청은 서로 독립적이어야 하며, 서버는 클라이언트의 상태를 저장하지 않습니다. 클라이언트는 요청에 필요한 모든 정보를 포함해야 합니다.

  • Client-Server
    클라이언트-서버 아키텍처는 클라이언트와 서버의 관심사를 분리합니다. 클라이언트는 사용자 인터페이스를 관리하고, 서버는 데이터 처리와 비즈니스 로직을 처리합니다.

  • Cacheable
    응답은 캐시 가능하거나 캐시 불가능하다고 명시적으로 표시되어야 합니다. 캐시 가능한 응답은 클라이언트에 의해 캐시될 수 있으며, 이를 통해 성능과 확장성이 향상됩니다.

  • Layered System
    REST 아키텍처는 여러 계층으로 구성될 수 있습니다. 각 계층은 특정 기능을 처리하며, 클라이언트는 최종 계층과만 상호 작용합니다. 이를 통해 시스템의 유연성이 증가하고, 각 계층의 독립적인 발전이 가능해집니다.

  • Code on Demand (optional)
    필요한 경우 서버는 클라이언트에 실행 가능한 코드를 제공할 수 있습니다. 이를 통해 클라이언트의 기능이 확장될 수 있습니다. 이 원칙은 선택 사항이며, 모든 REST API에서 적용되지는 않습니다.

이제 위 원칙에 대해서 차례대로 알아보도록 하겠습니다!

2. REST 아키텍처 스타일의 균일한 인터페이스 원칙

예를 들어, 온라인 쇼핑몰의 서버 API를 고려해봅시다. 이 경우 다음과 같은 엔드포인트가 있을 수 있습니다: 상품 조회, 상품 구매, 사용자 정보 조회, 사용자 주문 이력 조회 등입니다.

1. 리소스 식별(Identification of resources)

이 원칙은 URI(Uniform Resource Identifier)를 사용하여 모든 리소스를 고유하게 식별합니다. 각 엔드포인트는 고유한 URI를 가지며, 이를 통해 클라이언트가 해당 리소스에 액세스할 수 있습니다.

예: /products/{product_id} (상품 조회), /user/{user_id}/orders (사용자 주문 이력 조회)

2. 리소스 조작을 위한 표현(Manipulation of resources through representations)

클라이언트는 서버로부터 리소스의 표현(주로 JSON 또는 XML 형식)을 받아볼 수 있습니다. 클라이언트는 이 표현을 통해 리소스의 상태를 이해하고, 필요한 경우 이를 수정하여 서버에 다시 전송할 수 있습니다.

예를 들어, 사용자 정보를 가져오는 API가 있다고 가정해봅시다. 서버는 사용자 정보를 JSON 형식으로 제공합니다.

{
  "id": 123,
  "name": "John Doe",
  "email": "john.doe@example.com"
}

클라이언트는 이 정보를 바탕으로 사용자 이름을 변경하는 요청을 보낼 수 있습니다. 이때 클라이언트는 서버가 제공한 표현을 기반으로 새로운 상태를 생성하여 서버에 전송합니다. 예를 들어, 사용자의 이름을 변경하려면 클라이언트는 다음과 같은 요청을 보낼 수 있습니다.

PUT /users/123
Content-Type: application/json

{
  "name": "Jane Doe"
}

이 요청을 받은 서버는 해당 사용자의 이름을 'Jane Doe'로 업데이트하고, 업데이트된 사용자 정보를 다시 클라이언트에게 반환합니다:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 123,
  "name": "Jane Doe",
  "email": "john.doe@example.com"
}

3. 메시지 자체 설명성(Self-descriptive messages) 원칙

응답 메시지가 그 자체로 그 의미를 명확하게 전달해야 한다는 것을 의미합니다. 이는 HTTP 메서드 (GET, POST, PUT, DELETE 등), HTTP 상태 코드 (200, 404, 500 등), Content-Type 헤더 (application/json, text/html 등)를 통해 달성될 수 있습니다. 이 원칙에 따르면, 메시지를 받는 측은 메시지 내용을 이해하고 적절히 처리하는 데 필요한 모든 정보를 메시지 자체에서 찾을 수 있어야 합니다.

예를 들어, 아래 메시지는 새로운 사용자를 생성하는 POST 요청입니다.

POST /users
Content-Type: application/json

{
  "username": "newUser",
  "email": "newUser@example.com"
}

서버의 응답은 HTTP 상태 코드와 함께 올 것입니다.

HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": 124,
  "username": "newUser",
  "email": "newUser@example.com"
}

4. HATEOAS(Hypermedia as the Engine of Application State)

이 원칙은 클라이언트가 애플리케이션 상태를 탐색하고, 필요한 액션을 수행하기 위해 서버로부터 제공되는 하이퍼미디어 링크를 따르도록 함으로써, 클라이언트와 서버 간의 상호작용을 단순화하고 독립성을 유지하는 데 있습니다. 이 원칙은 클라이언트가 애플리케이션의 전체 상태를 이해할 필요 없이 서버의 응답만으로 원하는 작업을 수행할 수 있게 합니다.

즉, 요약하자면 서버가 클라이언트에게 보내는 응답이 리소스의 표현뿐만 아니라 리소스를 어떻게 처리해야 하는지에 대한 메타데이터도 포함하고 있는 것 입니다.

예를 들어, 서버에서 특정 사용자에 대한 정보를 반환할 때, 해당 사용자에 대해 수행할 수 있는 다른 작업들에 대한 링크를 함께 제공할 수 있습니다.

GET /users/123

HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 123,
  "username": "exampleUser",
  "email": "exampleUser@example.com",
  "links": {
    "self": "/users/123",
    "edit": "/users/123/edit",
    "delete": "/users/123"
  }
}

위의 예에서, 클라이언트는 사용자 정보를 얻는 데 필요한 링크(self), 사용자 정보를 수정하는 데 필요한 링크(edit), 사용자를 삭제하는 데 필요한 링크(delete) 등을 제공받습니다. 이렇게 하여 클라이언트는 서버의 상태를 더 쉽게 이해하고, 필요한 작업을 더 쉽게 수행할 수 있습니다.

이 원칙들은 REST 아키텍처 스타일의 균일한 인터페이스를 구성합니다. 이를 통해 클라이언트와 서버 간의 상호작용이 표준화되고, 다양한 클라이언트에서 사용할 수 있으며, 유지 관리 및 확장성이 향상됩니다.

3. Stateless 원칙

클라이언트-서버 간의 각 요청은 서로 독립적이어야 합니다. 서버는 클라이언트 상태를 저장하지 않으며, 클라이언트는 필요한 모든 정보를 요청에 포함해야 합니다.

Stateless 원칙에 따라, 서버는 클라이언트의 상태를 저장하지 않고, 각 요청은 독립적으로 처리됩니다. 이렇게 함으로써 서버는 더욱 확장성 있고 유연한 아키텍처를 가질 수 있으며, 여러 클라이언트와의 통신을 쉽게 처리할 수 있습니다.

예를 들어, 온라인 은행 애플리케이션을 고려해봅시다. 사용자는 다음과 같은 작업을 수행할 수 있습니다:

  1. 계좌 잔액 확인: 클라이언트 애플리케이션은 사용자 인증 정보와 함께 GET /accounts/{id}/balance 요청을 서버에 전송하여 계좌 잔액을 확인합니다. 서버는 요청을 처리하고 잔액 정보를 반환합니다. 이때 서버는 클라이언트의 상태를 저장하지 않습니다.

  2. 이체: 사용자가 다른 계좌로 이체를 하려면, 클라이언트 애플리케이션은 사용자 인증 정보, 이체 금액 및 대상 계좌 정보와 함께 POST /accounts/{id}/transfer 요청을 서버에 전송합니다. 서버는 이체를 처리하고 결과를 반환합니다. 이 경우에도 서버는 클라이언트의 상태를 저장하지 않습니다.

이러한 상황에서 Stateless 원칙을 따르면, 각 요청은 독립적으로 처리되므로 서버의 자원을 보다 효율적으로 사용할 수 있습니다. 또한, 클라이언트의 상태를 저장하지 않기 때문에 서버가 다운되거나 다른 서버로 전환되더라도 클라이언트 애플리케이션에 영향을 주지 않습니다. 클라이언트는 모든 필요한 정보를 요청에 포함시켜 서버에 전송하므로, 서버는 상태 정보를 저장할 필요가 없습니다. 이 원칙은 서버의 확장성과 유지 관리성을 높이는 데 도움이 됩니다.

4. Http Status

  • 100번 대 Inormational : 요청 정보를 처리중
  • 200번 대 Success : 요청을 정상적으로 처리함
  • 300번 대 Redirection : 요청을 완료하기 위해 추가 동작 필요
  • 400번 대 Client Error : 서버가 요청을 이해하지 못함
  • 500번 대 Server Error : 서버가 요청 처리 실패함

5. REST API 예제

온라인 상점의 RESTful API가 있다고 가정하고, 이 API는 다음과 같은 기능을 제공합니다.

  • 상품 목록 검색
  • 특정 상품 정보 검색
  • 상품 구매

이 기능을 제공하기 위해 다음과 같은 RESTful API 엔드포인트가 있을 수 있습니다:

  1. GET /products : 상품 목록을 검색합니다.
  2. GET /products/{id} : 특정 상품의 정보를 검색합니다.
  3. POST /orders : 새로운 주문을 생성하고 상품을 구매합니다.

이 예제에서는 REST 원칙이 적용되어 있습니다. 클라이언트는 상태가 없으며 각 요청이 독립적입니다. 클라이언트-서버 구조를 사용하고 있으며, 필요한 경우 클라이언트는 서버의 응답을 캐시하여 성능을 향상시킬 수 있습니다. 또한, 이 시스템은 여러 계층으로 구성될 수 있어 유연성과 확장성이 향상됩니다.

예를 들어, 온라인 상점의 클라이언트 애플리케이션은 다음과 같은 작업을 수행할 수 있습니다:

  1. 상품 목록 검색: 클라이언트 애플리케이션은 GET /products 요청을 서버에 전송하여 상품 목록을 검색합니다. 서버는 상품 목록을 JSON 형식으로 반환하고, 클라이언트 애플리케이션은 이 데이터를 사용하여 사용자 인터페이스를 업데이트합니다.

  2. 특정 상품 정보 검색: 사용자가 특정 상품을 클릭하면, 클라이언트 애플리케이션은 GET /products/{id} 요청을 서버에 전송하여 해당 상품의 정보를 검색합니다. 서버는 상품 정보를 JSON 형식으로 반환하고, 클라이언트 애플리케이션은 이 데이터를 사용하여 상품 상세 페이지를 표시합니다.

  3. 상품 구매: 사용자가 상품을 구매하려면, 클라이언트 애플리케이션은 POST /orders 요청을 서버에 전송하여 새로운 주문을 생성합니다. 서버는 주문 정보를 처리하고 주문이 완료되면 상태 코드와 함께 응답을 반환합니다.

이러한 방식으로 RESTful API는 클라이언트와 서버 간의 통신을 단순화하고, 다양한 플랫폼에서 쉽게 사용할 수 있는 인터페이스를 제공합니다. REST 아키텍처 원칙을 따르는 웹 서비스는 일관된 인터페이스를 가지고 있어 개발자들이 쉽게 이해하고 사용할 수 있습니다.

6. reference

https://bentist.tistory.com/37
https://meetup.nhncloud.com/posts/92
https://aws.amazon.com/ko/what-is/restful-api/

profile
가장 아름다운 정답은 서로의 협업안에 있다.

0개의 댓글