REST 그리고 RESTful API


💡 API(Application Programming Interface)란?

API는 흔히 ‘프로그램들이 소통할 수 있는 인터페이스’ 라고 한다.

예를 들면, 클라이언트가 “오늘 날씨 데이터”가 필요하다고 가정해봤다.

그러면 API는 클라이언트의 요청을 받아서 정리한 뒤, ‘날씨 데이터서버’에

“오늘 날씨에 대한 정보를 주세요”라고 요청을 하고 데이터를 받아와서

요청을 했던 클라이언트에게 날씨 정보를 반환해준다. 이렇게 API는

프로그램과 프로그램 사이에 있는 중간 전달자 역할을 수행한다고 이해했다.



💡 API Server란?

API 서버는 “규격화 되어 있는 서버”라고 할 수 있다.




💡 REST (REpresentational State Transfer)

REST는 Application 개발의 아키텍쳐 중 하나이다. 한국어로 직역을 해보면

‘대표 상태 전송’ 이다. 아키텍처가 너무 추상적이라 검색해 본 결과,

Application을 설계, 제작하는데 사용하는 패턴과 기술의 총칭이라고 한다.

또한 프로토콜에 독립적이고 일반적인 REST구현에서 HTTP를 사용한다.


REST의 개념을 좀 자세히 알아보았다.

1. Web Application 상에 존재하는 모든 리소스에 대해 고유의 URI을 부여한다.

2. HTTP method를 이용해 리소스에 CRUD 명령을 적용한다.

즉, 어떤 리소스에 대해 CRUD연산을 수행하기 위해 URI(URL)로 요청을 보내는 것이다.


RESTful API는 REST의 기준을 따르는 API정도로 이해했다.


추가적으로 URI와 URL에 대한 차이를 찾아보았는데,

URL은 Uniform Resource Locator로 인터넷 상 자원의 위치를 의미한다.

자원의 위치라는 것은 결국 어떤 파일의 위치를 의미한다.

반면에 URI는 Uniform Resource Identifier로 인터넷 상의 자원을

식별하기 위한 문자열의 구성으로, URI는 URL을 포함한다.



🔎 REST의 구성요소

REST의 구성 요소 다음 3가지의 요소로 구성된다.

1. 자원(Resource)

  • 자원은 클라이언트에서 액세스할 수 있는 모든 종류의 ‘개체/서비스’ 이다.

    모든 자원은 고유의 URI(URL)을 가지며 클라이언트는 이 URI를 지정하여

    해당 자원에 대해 CRUD 명령을 수행할 수 있습니다.

    (ex: https://adventure-works.com/orders/1)

2. 행위(Verb)

  • 행위는 클라이언트가 HTTP Method를 이용하여 자원을 조작하는 것을 의미합니다.

3. 표현(Representation)

  • 클라이언트가 HTTP Method로 자원을 조작하면 서버가 그에 대한 응답(JSON, XML)을

    보내는데 그것을 의미합니다.(요즘은 XML을 잘 사용안한다고 한다.)



🔎 REST의 특징

1. 서버-클라이언트 구조(Server-Client Architecture)

  • 서버는 API 제공, 클라이언트는 유저에 대한 처리를 전담하는 구조를 가지기 때문에

    서버와 클라이언트의 역할을 분명하게 구분할 수 있습니다.

2. 무상태성(Stateless)

  • HTTP를 이용하는 만큼 Stateless의 특성을 가집니다.

    각각의 요청에 대한 정보를 저장하지 않고 별개의 요청으로 처리합니다.

    덕분에 구현이 쉽고 서버의 부담을 덜어줄 수 있습니다.

    (ex. 검색창에 질문을 입력하고 엔터키를 누르는 형식으로 진행되는 온라인 검색)


  • Stateless의 반대 개념은 스테이트풀(Stateful)이다.

    Stateful상태의 웹의 경우 중간중간 정보가 저장되기 때문에 작업이

    중단되더라도 중단 된 곳부터 다시 시작할 수 있다. ​

3. 캐시 가능(Cacheable)

  • HTTP를 사용하기 때문에 웹의 기본 인프라를 사용할 수 있습니다. 따라서

    캐시 기능을 이용해 같은 URI에 대한 반복된 요청을 효율적으로 처리할 수 있습니다.


4. 일관된 인터페이스(Uniform Interface)

  • HTTP를 사용할 수 있는 환경이라면 플랫폼에 상관없이 사용할 수 있으며

    리소스의 타입에 상관 없이 같은 형태의 요청으로 처리됩니다.


아래는 Uniform Interface의 4가지 제약 조건이다,

1. Identification of resources(리소스가 URI로 식별되어야 한다.)

2. Manipulation of resources through representations (CRUD 명령시 메세지에 명시)

3. Self-descriptive messages

4. Hypermedia as the engine of application state(HATEOAS)


대부분의 REST API는 3번, 4번 제약 조건을 잘 만족하지 못한다고 한다.

그 이유에 대해 알아 보았다.

Self-descriptive messages는 메세지가 스스로 설명을 해야한다는 뜻이다.

아래 그림에서 왼쪽 그림은 목적지가 없어서 REST하지 않았다.

다음 그림에서 왼쪽 그림은 Content-Type이 맞지 않아서 REST 하지 않다.


HATEOAS는 하이퍼링크를 통한 전이를 의미한다.


그렇다면 왜 Uniform Interface가 필요할까? 바로 독립적인 진화를 하기 위해서다.

예를 들면 내가 개발한 서버에 새로운 API가 추가되고, 삭제될 경우 서버의

기능이 바뀌게 된다. 그러나 클라이언트는 업데이트를 할 필요가 전혀없다.

이게 바로 REST를 만들게 된 계기 이다.

결국 독립적인 진화가 로이 필딩이 REST를 만든 궁극적인 이유이다.


REST가 웹의 독립적 진화에 도움을 주었는가? YES

  1. HTTP에 지속적으로 여향을 줌

  2. Host 헤더 추가

  3. 길이 제한을 다루는 방법이 명시

  4. URI에서 리소스의 정의가 추상적으로 변경됨 ⇨ 식별하고자 하는 무언가


5. 자체적인 표현 구조(Self-Descriptiveness)

  • JSON, XML등을 이용하는 메세지 구조로 해당 메세지가 무엇을,

    어떤 행위를 의미하는지 직관적으로 이해할 수 있습니다.

    Json형식은 인간과 기계가 모두 읽을 수 있기 때문에 가장 널리 사용된다.


6. 계층 구조(Layered System)

  • 클라이언트는 대상 서버와 직접 통신하는지 아니면 중간 서버와 통신하는지 알 수

    없습니다. 따라서 클라이언트와 서버의 통신 사이에 보안이나 로드 밸런싱 등을

    위한 중간 계층을 추가할 수 있습니다.

    여기서 ‘로드 밸런싱’이란 네트워크 또는 서버에 가해지는 부하를 분산해주는 기술이다.



🔎 REST의 장점

1. 별도의 인프라 구축 필요x

  • HTTP를 사용하기 때문에 별도의 인프라를 구축할 필요가 없습니다.

2. 클라이언트와 서버의 분리

  • 클라이언트와 서버는 REST API를 통해 정보를 주고 받기 때문에

    둘 간의 역할이 명확하게 분리됩니다.

3. 플랫폼에 독립적

  • HTTP를 사용 가능한 환경이라면 플랫폼에 상관없이 사용 가능합니다.

4. 쉬운 사용

  • 메세지가 자체적으로 무엇을 의미하는지 표현하고 있기 때문에 사용이 쉽습니다.


🔎 REST의 단점

1. 표준이 존재하지 않음

  • 명확한 표준이 존재하지 않습니다. 따라서 REST의 특징을 따르지 않으면서

    REST API로 설계되는 이상한 API가 탄생할 수 있으며 관리가 어렵습니다.

2. HTTP Method의 한계

  • HTTP Method를 사용하기 때문에 CRUD라는 단순한 행위의 Method만 지원합니다.

3. RDBMS와 맞지 않음

  • REST에서는 리소스를 JSON, XML등의 형태로 표현하는데 이는 RDBMS와는 맞지 않는

    형태입니다. 그래서 NoSQL쪽이 더 선호되는 추세입니다.



💡 HTTP 메서드를 기준으로 기본 작업 정의

1. GET

↦ 리소스 표현, 응답 본문에 리소스의 세부 정보

2. POST

↦ 새 리소스 생성 요청. 요청 본문에 새 리소의 세부 정보를 제공

↦ 멱등성 미보장

3. PUT

↦ 기존 리소스를 전부 대체. 요청 본문에 갱신할 리소스 정보를 제공.

↦ 멱등성 보장

4. PATCH

↦ 기존 리소스를 부분 대체. 요청 본문에 갱신할 리소르 정보를 제공

↦ 멱등성 미보장

5. DELETE

↦ 지정 리소스 제거.


멱등성이 뭔지 모르겠어서 구글링을 했다.

동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고,

서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말한다.

GET, HEAD, PUT, DELETE 메서드는 멱등성을 가지며, POST 메서드는 그렇지 않다.

예를 들어, DELETE가 멱등성을 가진다는 것은, REST API에서 개발자는 DELETE메서드를

사용해 “목록의 마지막 항목 제거” 기능을 구현해서는 안된다는 것이다.



💡 REST API란?

REST API란 REST의 원리를 따르는 API를 의미한다. 그리고 지켜야하는 규칙이 있다.

1. URI는 동사보다는 명사를, 대문자보다는 소문자를 사용하여야한다.

2. 마지막에 “ / “ 를 포함하지 않는다.

3. 언더바(_) 대신 하이폰(-)을 사용한다.

4. 파일확장자는 URI에 포함하지 않는다.

5. 행위를 포함하지 않는다.

↦ http://example.com/delete-post/1 (X)

↦ http://example.com/post/1 (O)


🔎 왜 잘 안될까?

현재 REST API라고 부르는 대부분은 REST API가 아니다!. 왜일까?

흔한 웹페이지의 ‘미디어 타입’은 HTML이다. 반면에 HTTP API는 JSON을 사용한다.

둘의 큰 차이점은 HTML은 기계가 이해를 할 수 없는 언어이다.

HTML은 하이퍼링크가 있고, Self-descriptive가 된다.

하지만 JSON은 하이퍼링크가 정의되어 있지 않고, Self-descriptive가 불완전하다.


🔎 REST API로 고쳐보기

Self-descriptive 방법1. Media type

Media type을 새로하나 정의하고 Media type문서를 작성한다.

해당 문서에 “id”가 뭔지 의미를 정한다. IANA에 Media type을 등록한다.

성공적이지만 매번 Media type을 정해야하는 번거로움이 있다.


Self-descriptive 방법2. Profile

메세지에 Link: <https://example.com/test/>; rel="profile"라고 작성한다.

하지만 클라이언트 측에서 위 링크를 이해 못할수도 있다.


HATEOAS는 방법1. Data

본문에다가 그냥 링크를 넣거나 JSON으로 하이퍼링크를 표현하는 방법을

정의한 것들을 활용한다.


HATEOAS는 방법2. HTTP 헤더

Link, Locations 등의 헤더로 링크를 표현한다.



💡 RESTful이란?

RESTful이란 REST의 원리를 따르는 시스템을 의미한다.

하지만 REST를 사용했다고 하더라도 전부 RESTful 한 것은 아니라고 한다.

즉, REST API의 설계 규칙을 올바르게 지킨 시스템을 RESTful하다 말할 수 있다.


반면 REST API를 사용하였지만 RESTful 하지 못한 시스템은 아래와 같은 경우가 있다고 한다.

1. 모든 CRUD 기능을 POST로 처리 하는 API

2. URI 규칙을 올바르게 지키지 않은 API

3. REST API의 설계 규칙을 올바르게 지키지 못한 시스템




📚 References