REpresentational State Transfer
의 약자로, 웹의 장점을 최대한 활용할 수 있도록 2000년 로이 필딩이 제안한 네트워크 아키텍쳐 스타일이다. 여기서 스타일은 여러 REST
원칙들의 모음을 의미한다.
클라이언트와 서버 간의 관심사 분리를 통해, 클라이언트는 이식성(portability)을 개선하고, 서버는 확장성(scalability)을 개선시킨다. 느슨한 결합
으로 연결된 두 영역은 의존성이 줄어들어 독립적으로 발전하기 수월해진다.
클라이언트와 서버 간의 통신에는 본질적으로 상태가 없어야(Stateless)
한다. 즉, 클라이언트는 보낼 때 필요한 모든 데이터를 담아 서버에 요청을 보내고, 세션 등의 상태는 클라이언트에 보관한다. 서버측 자원은 이용할 수 없다. 서버는 클라이언트의 이전 요청을 기억할 필요가 없다. 이로 인해 다음과 같은 효과를 얻는다.
요청에 대한 전체적인 특징을 파악하기 위해 해당 요청외에 다른 것들을 고려하지 않아도 됨. 가시성의 향상
부분적인 장애를 복구하기 위해서 고려해야할 것들이 많지 않기 때문에 복구가 용이해짐. 신뢰성의 향상
서버측 컴포넌트가 요청에 대한 정보를 저장하지 않아도 되기 때문에 리소스를 확보할 수 있고, 요청에 대한 정보를 관리하지 않기 때문에 구현이 더욱 쉬워짐. 확장성의 향상
단점으로는 반복되는 요청으로 인해 네트워크 성능 저하가 일어날 수 있고, 서버의 일관된 관리를 받을 수 없다는 점이다.
HTTP의 캐시(Cache)
를 이용하여 캐싱 가능 여부를 지정할 수 있다. 캐시를 사용하면 통신 지연 시간을 줄일 수 있어 트워크 효율성, 확장성, 사용자 만족도를 향상시킬 수 있다. 단, 오래된(stale)
데이터가 캐싱되어 있다면 신뢰성이 저하된다.
자원에 대한 정보 전송 형태를 표준화하여 HTTP
표준을 따른다면 플랫폼에 상관없이 사용할 수 있다. 표준이 있으므로 아키텍처 설계가 단순화하고, 가시성이 향상된다. 구현체들은 독립적으로 발전할 수 있다.
여기에는 4가지 원칙이 적용된다.
클라이언트와 서버 사이를 다중 계층으로 구성할 수 있고, Proxy
나 Gateway
, 공유 캐시
등 네트워크 중간 매체를 사용할 수 있다.
필요에 따라 선택할 수 있는 제약으로, 서버에서 보낸 코드를 클라이언트에서 설치하고 실행할 수 있게 하여 클라이언트를 단순화할 수 있다.
이러한 REST
를 기반으로 구현한 API를 REST API
라고 하며, 몇 가지 규칙이 있다.
URI
는 정보의 자원을 표현해야 한다.# 1번 user의 정보를 요청한다면
GET /users/1 ⭕
GET /users/get/1 ❌
자원 외에 행위가 포함되는 것은 적절하지 않다.
HTTP Method(GET, POST, PUT, PATCH, DELETE)
로 표현한다.# 새로운 user를 등록할 때
POST /users/register ⭕
GET /users/register ❌
새로운 user 등록은 자원을 작성하는 행위이므로 POST
가 알맞다. GET
은 데이터를 가져옮을 의미한다.
PUT
은 전체 데이터 수정, PATCH
는 일부 데이터 수정, DELETE
는 데이터 삭제를 의미하므로, 그것에 맞춰 Method
를 사용한다.
http://example.com/users/1/resume
http://example.com/notices
http://example.com/users/register/ ❌
http://example.com/users/register ⭕
URI
의 모든 글자는 자원의 유일한 식별자 역할을 하며, URI
가 다르면 자원도 달라야 한다. 통신에 혼동을 주지 않기 위해 분명한 URI
를 사용해야 하며, 따라서 마지막에는 /
를 포함하지 않는다.
밑줄(_)
은 UI에 따라 가려지기도 하고 보기 어려우므로 대신 하이픈(-)
을 사용하여 가독성을 높인다.
http://example.com/posts/밑줄_보다는_하이픈_사용 ❌
http://example.com/posts/밑줄-보다는-하이픈-사용 ⭕
RFC 3986(URI 문법 형식)은 URI 스키마와 호스트를 제외하고는 대소문자를 구별하도록 규정하기 때문에 URI 경로에 대문자 사용은 피하도록 해야 한다. 대소문자에 따라 다른 리소스로 인식한다.
http://example.com/users/Register ❌
http://example.com/users/register ⭕
자원 포맷을 나타내는 파일 확장자는 URI
대신 Accept header
를 사용한다.
http://example.com/users/1/resume/photo.jpg ❌
GET /users/1/resume/photo HTTP/1.1 Host: example.com Accept: image/jpg ⭕
리소스 간에 관계가 있는 경우, /리소스명/리소스 ID/관계가 있는 다른 리소스명
으로 URI를 구성한다.
GET : /users/{userid}/resume (일반적으로 소유 ‘has’의 관계를 표현할 때)
잘 설계된 REST API는 응답 코드 역시 적절하게 전송해야 한다.
코드 | 설명 |
---|---|
1xx | 정보 응답 |
2xx | 성공 응답 |
3xx | 리다이렉트 |
4xx | 클라이언트 요청 오류 |
5xx | 서버 오류 |
위와 같은 REST API
규칙을 잘 지켜 설계한 API를 RESTful한 API
라고 한다. RESTful
을 강조하는 이유는 이해와 사용이 쉬운 API를 설계하기 위함이다.
성능 보다는 API에 대한 이해와 호환성에 맞춘 것이므로, 성능이 중요하다면 무조건 지켜야 할 사항은 아니다.
참고
Amazon - RESTful API란 무엇입니까?
NHNCloud - REST API 제대로 알고 사용하기\
위키백과 - REST
spoqa - REST 아키텍처를 훌륭하게 적용하기 위한 몇 가지 디자인 팁
heejeong Kwon - [Network] REST란? REST API란? RESTful이란?
coco3o - REST란? REST API 와 RESTful API의 차이점
Do KY - [REST API] Roy Fielding 의 REST API 논문 번역 및 이해(1)
Do KY - [REST API] Roy Fielding 의 REST API 논문 번역 및 이해(2)
johnna_endure - REST에 대한 정리글 [로이 필딩 논문을 훑어본 뒤...]