Rest, Restful, Restful API

웹개발을 하다보면 Rest, Restful, Restful API라는 단어에 대해 많이 들어보게 됩니다. 실제로 Restful API를 다룰줄 알며, 이미 현업에서 쓰고있음에도 불구하고 Rest, Restful, Restful API에 대한 설명을 하라고 한다면 선뜻 입에서 나오지 않는 경우가 있습니다. 현재 하고있는 이 Rest에 대해 대략적으로는 알고 있지만 정확히 알아가기 위해 이 개념에 대해 알 필요가 있습니다. 누군가가 Rest가 무엇인지 Restful, Restful API가 무엇인지 묻는다면 말이죠.

Rest(REpresentational State Transfer)

REST란 직역하면 ‘대표적인 상태 전달’ 이며, World Wide Web과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처 스타일입니다. 그래서 이 아키텍쳐의 스타일을 따라야 “Rest 하다” 라고 볼 수 있습니다. 아키텍처 스타일은 즉 Rest의 제약조건의 집합이라고 할 수 있는데 이 집합에는 6가지(Client-Server, Stateless, Cacheable, Uniform Interface, Layered System, Code on demand)가 있으며 아래와 같습니다.
Rest에 대해 알아보면 Restful이라는 말이 있는데, 이 Rest의 6가지 제약조건들을 모두 지키는 HTTP 통신을 'Rest를 따른다' ,'Restful 하다' 라고 말할 수 있으며, 이 제약조건들을 모두 지키는 Restful한 API를 Restful API라고 부릅니다.
* Rest에 대한 정확한 정의는 https://restfulapi.net/에 기술되어 있습니다.

Client-Server

클라이언트와 서버는 서로 의존하지 않으며 클라이언트에서는 서버의 리소스 URI에 대해서만 알고 있으면 됩니다.
클라이언트가 서버에 요청할 때 서버의 언어가 무엇인든, 코드가 어떻게 돼있든 서버에서 받아들일 수 있는 URI만 알고있으면 되기때문에 독립돼있는 영역입니다.

Stateless

서버는 서버측에서 클라이언트 세션에 대한 상태를 저장하지 않는데, 이 상태를 Stateless라고 합니다.
서버는 클라이언트 세션에 대한 상태를 저장하지 않기 때문에, 클라이언트에서 서버로 요청을 할 때는 필요한 모든 정보가 포함되어야 하며, 서버에 저장된 Context를 클라이언트 측에서 활용할 수 없습니다. 따라서 세션 상태는 전적으로 클라이언트에서 유지되므로, 클라이언트는 클라이언트 측에서 모든 응용 프로그램 상태관련 정보를 저장하고 처리해야 합니다.
모든 HTTP요청은 완전히 격리 돼있으며 서버는 이전에 요청한 정보에 의존하지 않고 각각의 요청에 독립적으로 반응합니다.

Stateless의 장점으로는 다음과 같습니다
- 여러서버에 API를 배포하여 수백만명의 동시 사용자로 확장하는데 도움이 됩니다. 세션관련 종속성이 없기 때문에 어떤서버라도 요청을 처리할 수 있습니다. - 모든 서버측 상태 동기화 로직을 제거하여 Rest API의 복잡성을 줄일 수 있습니다 - API를 캐시하기 쉽습니다. 하나의 요청을 보내는 것만으로 HTTP요청의 결과를 캐시할지 여부를 결정할 수 있습니다. 이전이 캐시에 영향을 줄 불확실성은 없으며, 응용프로그램의 성능을 향상시킬 수 있습니다. - 클라이언트에서 요청시 모든 정보를 보내기 때문에 서버에서는 클라이언트가 어디에 있는지 추적하지 않습니다.

Cacheable

클라이언트에서 요청을 할 때 캐시를 할지말지 명시해야 합니다. 응답을 캐시할 수 있다면 클라이언트에서 동일한 요청이 왔을 때 응답데이터를 재사용 할 수있어야 합니다.
Cache-Control헤더를 통한 캐시여부를 명시할 수 있습니다

Uniform Interface

어떠한 아키텍처를 준수해야 한다는 의미이며 통일된 아키텍쳐로 어떠한 기술 및 프레임워크 환경에 관련없이 사용할 수 있게합니다. 즉 HTTP요청을 보낼때 지켜야 하는 정형화된 규칙입니다.

- Identification of resources(URI)
시스템 리소스에는 하나의 논리적인 URI만 있어야 하며 관련데이터를 가져오는 방법을 제공해야 합니다. Rest에서는 리소스를 특정짓는 명칭을 동사형이 아닌 명사형을 권장하고 있으며 Web상에서 URI를 통해 HTTP METHOD와 함께 접근될 수 있습니다.
Ex) www.domain.com/user/information?no=1

- Manipulation of resources through representations
Client와 Sever사이에 리소스에 대한 상태나 정보가 담긴 Representation를 통해서 데이터를 주고받습니다. 리소스는 하나이상의 Representation를 가질 수 있으며 형태는 Content-Type(MIME type)으로 결정됩니다. Content-Type(MIME type)은 여러가지가 있으며 동일한 리소스에 대해 여러가지의 Content-Type(MIME type)포맷을 가질 수 있습니다.
Content-Type : https://www.iana.org/assignments/media-types/media-types.xhtml

- Self-descriptive messages
메시지는 스스로 가진 리소스정보를 설명할 수 있어야 한다. 정보들은 Http Method, Http status code, Http Header등을 활용해서 정보를 전달하거나 전달받아야 한다.
예를 들어 다음과 같은 메시지가 있다고 할때 Url이 빠지거니 Method가 빠지게 되면 Self-descriptive message가 아니게 됩니다.
또한 Header에 Content-Type이 명시돼있지 않을 경우에도 전송하려는 리소스가 어떤타입인지 불분명해서 Self-descriptive message가 아닌 메시지가 됩니다.

Request URL: http://localhost:4000/web/rest
Request Method: GET
Status Code: 200 OK
Content-Type: application/json

- Hypermedia AS The Engine Of Application State(HATEOAS)
HTTP응답으로 다음으로 수행할 Action을 Link나 Location을 이용하여 리턴합니다.

Http Header 활용

Request URL: http://localhost:4000/web/rest
Request Method: GET
Status Code: 200 OK
Content-Type: application/json
Location: user/1

Link 활용

{
    "data":{
        "id":1,
        "type": "user",
        "link": "http://www.service.com/user/1"
    },
}

Layered System

Rest를 이용하여 계층화된 시스템을 사용하게 되면 비즈니스로직(주로 3계층)아키텍처를 구현할 수 있게됩니다.

3계층 아키텍처(3-Tier Architecture)는 브라우저에서 HTTP요청시 클라이언트 계층 -> 어플리케이션 계층 -> 데이터 계층으로 전달하는 구조입니다.
주로 사내 어플리케이션의 비즈니스 로직으로 사용되는 구조입니다.

Jekyll

출처 : https://www.tonymarston.net/php-mysql/3-tier-architecture.html

Code on demand(Optional)

Code on demand란 서버에서 클라이언트로 코드를 보내면 클라이언트는 이 코드를 수행할 수 있어야 한다는 것입니다. javascript를 의미하며 이 조건은 꼭 충족할 필요는 없는 요건입니다.

Ex) 응답이 alert("Success"); 로 왔을 경우 클라이언트 에서는 이 코드를 실행할 수 있어야 합니다.