어느덧 경력이 2년이 되었으나 아직도 REST에 대해 명확히 설명하지 못하는 부끄러운 단계여서,,
유튜브채널 naver d2에서 '그런 REST API로 괜찮은가' 테크강의와 위키백과를 보며 REST에 대해 정리해보았다.
REST
정의
Representational State Transfer 표현적인 상태전송
a way of providing interoperability between computer systems on the Internet.
컴퓨터 시스템간의 상호운용성을 제공하는 방법
< 분산 하이퍼미디어 시스템 (ex: 웹)을 위한 아키텍쳐 스타일 (제약조건의 집합) >
사실 정의만 봐서는 잘 와닿지 않는다.
배경
1. WEB의 등장 (1991)
- 표현형식 : HTML (정보를 하이퍼텍스트로 연결)
- 식별자 : URI
- 전송방법 : HTTP (프로토콜)
HTTP 명세가 추가되며 기존의 웹을 망가뜨리지 않고 HTTP를 반영할 방법에 대해 고민하게 됨
HTTP Object Model 등장 > 나중에 REST 라는 이름으로 발표 (2000)
(Roy T. Fielding - "Architectural Styles and the Design of Network-based Software Architectures")
2. API 등장
XML-RPC (MS) > SOAP (Salesforce) > REST (Flickr) > 점점 규칙이 적고 간결해짐
MS의 REST API 가이드라인 (2016)
- URI 형식 : https://{serviceRoot}/{collection}/{id}
- 메소드지원 : GET, PUT, DELETE, POST, HEAD, PATCH, OPTIONS
- 버저닝 : Major.minor 버전정보는 URI 에 포함
REST API
REST 아키텍쳐 스타일(제약조건의 집합)을 모두 따르는 API
RESTful : Fielding 의 REST 원리를 따르는 시스템
REST 제약조건
- 인터페이스 일관성 (Uniform Interface) : 일관적인 인터페이스로 분리되어야 한다
- For 독립적 진화 : 서버와 클라이언트는 각각 독립적으로 진화함 > 서버 기능이 변경되어도 클라이언트 업데이트 할 필요 없음 > HTTP, HTML 명세가 변경되어도 웹은 잘 동작함
- Uniform Interface 제약조건 (4개)
- 1) identification of resources : 리소스는 URI로 식별되어야함
- 2) manipulation of resources through representations : 표현을 통해 리소스를 제작해야함 > 리소스를 생성/수정/삭제할 때 메시지에 표현을 담아 전송해야하는 것
- 3) self-descriptive messages : 메시지에 설명이 있어야함 > 확장가능한 커뮤니케이션 = 서버/클라이언트가 변경되어도 오고가는 메시지는 언제나 해석가능함 > 현재 HTTP 요청/응답메시지에는 설명 없음
- 4) hypermedia as the engine of application state (HATEOAS) : 애플리케이션 상태는 하이퍼링크를 통해 전이되어야함 (Late binding) > 전이가 완료된 후에 다음으로 전이될 상태가 결정됨 = 링크는 동적으로 변경될 수 있어야함
- 오늘날 REST API는 대체로 3,4 번은 못 지키고 있음
- 무상태(Stateless) : 각 요청 간 클라이언트의 콘텍스트가 서버에 저장되어서는 안 된다
- 캐시 처리 가능(Cacheable): WWW에서와 같이 클라이언트는 응답을 캐싱할 수 있어야 한다.
잘 관리되는 캐싱은 클라이언트-서버 간 상호작용을 부분적으로 또는 완전하게 제거하여 scalability와 성능을 향상시킨다. - 계층화(Layered System): 클라이언트는 보통 대상 서버에 직접 연결되었는지, 또는 중간 서버를 통해 연결되었는지를 알 수 없다. 중간 서버는 로드 밸런싱 기능이나 공유 캐시 기능을 제공함으로써 시스템 규모 확장성을 향상시키는 데 유용하다.
- Code on demand (optional) : 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다. (ex. 자바 애플릿, 자바스크립트)
- 클라이언트/서버 구조 : 아키텍처를 단순화시키고 작은 단위로 분리(decouple)함으로써 클라이언트-서버의 각 파트가 독립적으로 개선될 수 있도록 해준다
결론적으로 REST로 인해 웹의 독립적 진화가 가능해짐
- HTTP에 지속적으로 영향을 줌
- Host 헤더 추가 / 길이제한 다루는 방법 명시 (ex. 414 URI Too Long) / URI의 리소스 정의가 추상적으로 바뀜
- REST API를 개발/ HTTP API를 개발/ (현재상태) 개발한 것을 그냥 REST API 라고 부르는것
현재 REST API를 구현하기 힘든 이유
WEB = 사람이 보는 것 , Media type = html, 하이퍼링크, self-descriptive (html 명세)
HTTP = 기계가 해석, Media type = Json, 하이퍼링크 X, non self-descriptive (key-val 정의 없음)
> Self-descriptive 해결하기 위한 노력
- json에 미디어타입을 정의한 뒤 미디어타입 문서를 만들어 self description 정의 > IANA에 등록 (모든 미디어타입)
- 단점 : 매번 미디어타입 정의 필요
- json에 명세한 문서 링크를 추가해 Profile 작성
- 단점 : 클라이언트가 Link 헤더(RFC 5988)와 profile (RFC 6906)을 알아야함.
- Content negotiation 할 수 없음
> HATEOAS 해결하기 위한 노력 : data, 헤더 모두 활용
- data(json 본문)에 다양한 방법으로 하이퍼링크 표현
- 단점 : 링크를 표현하는 법을 직접 정의해야함
- HTTP 헤더로 링크 표현 (Link, Location 등)
- 정의된 relation만 활용하면 표현에 한계가 있음
정리
- 오늘날 대부분의 REST API는 사실 REST 를 따르지 않음 (self-descriptive, HATEOAS 불만족)
- REST는 진화하는 웹 어플리케이션을 위한 것이다.
- REST를 따를지는 API 설계자들이 스스로 판단해 결정해야한다.
Reference
- Naver D2 : 그런 REST API로 괜찮은가
- 위키백과 : REST
'Web' 카테고리의 다른 글
프레임워크 vs 라이브러리 (vs API) 비교, 표준 라이브러리, 런타임 라이브러리 (2) | 2021.06.16 |
---|---|
GraphQL - REST API와 비교 (0) | 2021.06.15 |