188일차 - REST API

김민찬·2021년 11월 14일
0

취업으로의 여정

목록 보기
195/196
post-thumbnail
post-custom-banner

짧은 정리

REST의 가장 중요한 특성: 각 요청이 어떤 동작이나 정보를 위한 것인지를 그 요청의 모습 자체로 추론이 가능함.

REST API에서는 HTTP 규약에 따라 신호를 전송한다.
GET: 특정 리소스의 표시를 요청, 오직 데이터를 받기만 한다.
POST: 특정 리소스에 생성요청을 보낸다.
PUT: 목적 리소스에 모든 현재 표시를 요청 Payload로 바꾼다.
DELETE: 특정 리소스를 삭제한다.

(추가적으로 PATCH를 사용하기도 한다)
PATCH: 리소스의 일부만을 수정한다.

POST, PUT, PATCH는 body가 존재해서 정보를 안전하고, 많이 실어서 보낼 수 있다.

하지만 이 요청들의 기능이 특정 용도로 제한되어 있지는 않지만, 누구나 요청의 의도를 파악하기 위해 위의 규칙을 지키는게 좋다.

REST API란 HTTP 요청을 보낼때, 어떤 URI에 어떤 메소드를 사용할지, 개발자들 사이에 지켜지는 규칙이다.


상세정리

naver d2의 그런 REST API로 괜찮은가?를 개인적으로 정리한 블로깅입니다

REST의 등장

REST(REpresentational State Transfer): '웹에 존재하는 모든 자원(이미지, 동영상, DB자원)에 고유한 URI를 부여해 활용'하는 것

Roy T.Fielding(로이 필딩)이 1994년부터 1996년 웹을 망가뜨리지 않고 HTTP를 증폭시킬 수 있을까라는 고민을 하다가 HTTP Object Model이라는 것을 만든다.

그리고 이름을 REST로 바꾸고 논문으로 발표한다.

REST API

REST 아키텍쳐 스타일을 따르는 API

REST?: 분산 하이퍼 미디어 시스템(ex: 웹)을 위한 아키텍쳐 스타일

하이퍼미디어: 그래픽, 오디오, 영상, 완전한 텍스트, 그리고 하이퍼링크가 비선형인 매체
아키텍쳐 스타일: 제약조건들의 집합 (제약조건을 모두 지켜야 REST이다)

REST를 구성하는 스타일

  1. client-server(클라이언트/서버 구조): 아키텍처를 단순화시키고 작은 단위로 분리(decouple)함으로써 클라이언트-서버의 파트가 독립적으로 개선될 수 있도록 해준다.
  2. stateless(무상태성): 각 요청 간 클라이언트의 콘텍스트가 서버에 저장되어서는 안된다.
  3. cachable(캐시 처리 가능): WWW에서와 같이 클라이언트는 응답을 캐싱할 수 있어야 한다.(캐시는 컴퓨터의 성능을 향상시키기 위해 사용되는 메모리로, 캐시영역으로 데이터를 가져와서 접근하는 방싱을 캐싱이라고 한다)
  4. uniform ubterface(인터페이스 일관성): 일관적인 인터페이스로 분리되어야 한다.
  5. layered system(게층화): 클라이언트는 RREST API 서버만 호출한다. REST 서버는 다중 계층으로 구성될 수 있으며 로드 밸런싱(부하 분산), 암호화, 사용자 인증 등을 추가하여 구조상의 유연성을 둘 수 있다.
  6. code-ondemand(optional): 자바 애플릿이나 자바스크립트의 제공을 통해 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다.

이중에서 Uniform Interface(인터페이스 일관성)을 가장 지키지 못한다.

Uinfrom Interface이 제약조건

  • 리소스가 URI로 식별되어야한다.
  • 리소스를 CRUD를 할때 HTTP메시지에다가 표현을 담아서 전송해야한다.
  • 메시지는 스스로를 설명해야한다(Self-descriptive)(메시지의 내용으로 온전히 해석이 가능해야 한다.)
  • 애플리케이션의 상태는 하이퍼링크를 이용해 전이되어야한다.(HATEOAS)

WHY?

왜 인터페이스 일관성을 지켜야하나?

  • 서버와 클라이언트가 각각 독립적으로 진화한다.
  • 서버의 기능이 변경되더라도 클라이언트를 업데이트할 필요가 없다.(서버가 바뀐다해도 클라이언트가 바뀌면 안된다.)
  • REST를 만들게 된 계기: '웹을 망가뜨리지 않고, HTTP를 증폭시키기 위해'

웹들은 REST를 잘 지키고 있나

매우 잘 지키고있다 이유는?

  • 웹 페이지를 변경했다고 웹 브라우저를 업데이트할 필요는 없다.
  • 웹 브라우저를 업데이트했다고 웹 페이지를 변경할 필요도 없다.
  • HTTP 명세가 변경되어도 웹은 잘 동작한다.(version up)
  • HTML 명세가 변경되어도 웹은 잘 동작한다.(version up)

REST API

REST API는 하이퍼텍스트를 포함한 스스로 설명가능(self-descriptive)한 메시지의 인터페이스 일관성(uniform interface)을 통해 리소스에 접근하는 API

REST API를 꼭따라야 할까?
로이 필딩의 답은 '아니다' 이다.
-> "서버와 클라이언트를 모두 스스로 만들어서 시스템 전체를 통제할 수 있거나, 업데이트에 관심이 없으면, REST에 대해 따지느라 시간을 낭비하지 말아라."

비교

흔한 웹 페이지HTTP API
ProtocolHTTPHTTP
커뮤니케이션사람-기계기계-기계
Media TypeHTMLJSON

커뮤니케이션에서 문제가 발생한다.

HTMLJSON
Hyperlink됨 (a 태그 등)정의되어있지 않음
Self-descriptive됨 (HTML 명세)불완전*

*문서 해석은 가능하지만, 의미를 해석하려면 별도로 문서가(API 문서 등) 필요하다.

ex)

[
  {"id": 1, "title": "회사 가기"},
  {"id": 2, "title": "집에 가기"}
]

"id"가 무엇을 의미하고, "title"이 무엇을 의미하는지 알 방법은 없다.

Self-descriptive(메시지의 스스로 설명)와 HATEOAS(하이퍼링크를 통한 전이)가 독립적 진화에 어떻게 도움이 되는 것인가?

Self-descriptive - 확장 가능한 커뮤니케이션을 가능하게 한다.
서버나 클라이언트가 변경되더라도 메시지를 해석할 수 있다.
HATEOAS - 애플리케이션 상태 전이의 late binding
어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다.(페이지1을 눌러서 이동 -> 페이지1에 가서야 다음 페이지2로 이동가능)
-> 링크는 동적으로 변경될 수 있다.(서버가 링크를 바꿔도 클라이언트의 동작은 문제가 없다.)

Self-descriptive를 지키는 방법

방법1: Media type
1. 미디어 타입을 하나 정의한다.
2. 미디어 타입 문서를 작성한다. 이 문서에 "id"가 뭐고 "title"이 뭔지 의미를 정의한다.
3. IANA(모든 미디어 타입이 정의되어 있음)에 미디어 타입을 등록한다. 이 때 만든 문서를 미디어 타입의 명세로 등록한다.(정해진 Form을 채워서 등록)
4. 이제 이 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 이 메시지의 의미를 온전히 해석할 수 있다.

단점

  • 매번 미디어 타입을 정의해야한다.(회사의 모든 사람이 미디어 타입을 이해하고 있으면, 이런 수고를 하지 않아도 되긴한다.)

방법2: Profile
1. "id"가 뭐고 "title"이 뭔지 의미를 정의한 명세를 작성한다.
2. Link 헤더에 profile relation으로 해당 명세를 링크한다.
3. 이제 메시지를 보는 사람은 명세를 찾아갈 수 있으므로 이 문서의 의미를 온전히 해석할 수 있다.

단점

  • 클라이언트가 Link 헤더(RFC 5988)와 profile(RFC 6906)을 이해해야 한다.
  • Content negotiation을 할 수 없다.(미디어타입 방법은 클라이언트가 이를 지원하지 못할때 서버가 알아차릴 수 있는데, 미디어타입으로 판단하는 것이 아니라 오로지 링크 헤더로만 판단하기 때문)

HATEOAS를 지키는 방법

방법1: data로 하이퍼링크를 표현
ex 1)

[
  {
    "link": "https://example.org/todos/1",
    "title": "회사 가기"
  },
  {
    "link": "https://example.org/todos/2",
    "title": "집에 가기"
  }
]

ex 2)

[
  "links": {
  	"todo": "https://example.org/todos/{id}"
  },
  "data": [{
    "id": 1,
    "title": "회사 가기"
  }, {
    "id": 2, 
    "title": "집에 가기"
  }]
]

단점

  • 링크를 표현하는 방법을 직접 정의해야한다.

JSON으로 하이퍼링크를 표현하는 방법을 정의한 명세들을 활용하는 방법도 있다.(ex: JSON API)

단점

  • 기존 API를 많이 고쳐야한다.

방법2: Link, Location 등의 헤더로 링크를 표현한다.

단점

  • 정의된 relation만 활용한다면 표현에 한계가 있다.

참고자료

얄팍한 코딩사전 - REST API가 뭔가요?
naver d2 - 그런 REST API로 괜찮은가
위키백과 - REST
stampid.log - REST API와 RESTful API
홍찬기 - REST란

profile
두려움 없이
post-custom-banner

0개의 댓글