til-no | title | tags | createdAt |
---|---|---|---|
5 |
CS - REST/RESTful API |
cs |
2023.05.22 |
REpresentational State Transfer
의 약자로, 웹의 장점을 최대한 활용할 수 있도록 2000년 로이 필딩이 제안한 네트워크 아키텍쳐 스타일이다. 여기서 스타일은 여러 REST
원칙들의 모음을 의미한다.
클라이언트와 서버 간의 관심사 분리를 통해, 클라이언트는 **이식성(portability)**을 개선하고, 서버는 **확장성(scalability)**을 개선시킨다. 느슨한 결합
으로 연결된 두 영역은 의존성이 줄어들어 독립적으로 발전하기 수월해진다.
클라이언트와 서버 간의 통신에는 본질적으로 상태가 없어야(Stateless)
한다. 즉, 클라이언트는 보낼 때 필요한 모든 데이터를 담아 서버에 요청을 보내고, 세션 등의 상태는 클라이언트에 보관한다. 서버측 자원은 이용할 수 없다. 서버는 클라이언트의 이전 요청을 기억할 필요가 없다. 이로 인해 다음과 같은 효과를 얻는다.
-
요청에 대한 전체적인 특징을 파악하기 위해 해당 요청외에 다른 것들을 고려하지 않아도 됨. 가시성의 향상
-
부분적인 장애를 복구하기 위해서 고려해야할 것들이 많지 않기 때문에 복구가 용이해짐. 신뢰성의 향상
-
서버측 컴포넌트가 요청에 대한 정보를 저장하지 않아도 되기 때문에 리소스를 확보할 수 있고, 요청에 대한 정보를 관리하지 않기 때문에 구현이 더욱 쉬워짐. 확장성의 향상
단점으로는 반복되는 요청으로 인해 네트워크 성능 저하가 일어날 수 있고, 서버의 일관된 관리를 받을 수 없다는 점이다.
HTTP의 캐시(Cache)
를 이용하여 캐싱 가능 여부를 지정할 수 있다. 캐시를 사용하면 통신 지연 시간을 줄일 수 있어 트워크 효율성, 확장성, 사용자 만족도를 향상시킬 수 있다. 단, 오래된(stale)
데이터가 캐싱되어 있다면 신뢰성이 저하된다.
자원에 대한 정보 전송 형태를 표준화하여 HTTP
표준을 따른다면 플랫폼에 상관없이 사용할 수 있다. 표준이 있으므로 아키텍처 설계가 단순화하고, 가시성이 향상된다. 구현체들은 독립적으로 발전할 수 있다.
여기에는 4가지 원칙이 적용된다.
- identification of resources (리소스의 식별)
- 요청은 리소스를 식별해야 한다. 이를 위해 균일한 리소스 식별자를 사용한다.
- manipulation of resources through representations (표현 계층을 통한 리소스 조작)
- 클라이언트는 원하는 경우 리소스를 수정하거나 삭제하기에 충분한 정보를 리소스 표현에서 가지고 있다. 서버는 리소스를 자세히 설명하는 메타데이터를 전송하여 이 조건을 충족한다.
- self-descriptive messages (자기 표현적인 메세지)
- 클라이언트는 표현을 추가로 처리하는 방법에 대한 정보를 수신한다. 이를 위해 서버는 클라이언트가 리소스를 적절하게 사용할 수 있는 방법에 대한 메타데이터가 포함된 명확한 메시지를 전송한다.
- hypermedia as the engine of application state (애플리케이션 상태 전이 엔진으로서의 하이퍼미디어)
- 클라이언트는 작업을 완료하는 데 필요한 다른 모든 관련 리소스에 대한 정보를 수신한다. 이를 위해 서버는 클라이언트가 더 많은 리소스를 동적으로 검색할 수 있도록 표현에 하이퍼링크를 넣어 전송한다.
클라이언트와 서버 사이를 다중 계층으로 구성할 수 있고, Proxy
나 Gateway
, 공유 캐시
등 네트워크 중간 매체를 사용할 수 있다.
필요에 따라 선택할 수 있는 제약으로, 서버에서 보낸 코드를 클라이언트에서 설치하고 실행할 수 있게 하여 클라이언트를 단순화할 수 있다.
이러한 REST
를 기반으로 구현한 API를 REST API
라고 하며, 몇 가지 규칙이 있다.
# 1번 user의 정보를 요청한다면
GET /users/1 ⭕
GET /users/get/1 ❌
자원 외에 행위가 포함되는 것은 적절하지 않다.
# 새로운 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에 대한 정리글 [로이 필딩 논문을 훑어본 뒤...]