이전에 포스팅한 'Roy Fielding의 논문을 통한 REST'를 간단하게 다시 정리해보고자 한다.
REST는 HTTP 프로토콜을 기반으로 하는 분산형 하이퍼미디어 시스템 (Distributed Hypermedia System)을 위한 아키텍처 스타일이다.
즉, HTTP 프로토콜을 통해 API를 설계하기 위한 아키텍처 스타일
자원 (RESOURCE) - URI
행위 (Verb) - HTTP Methods
표현 (Representations)
REST는 아래의 6가지 제약조건을 사용하며, 이 제약조건을 따르는 인터페이스를 REST API라고 할 수 있다.
아래의 제약조건들이 REST의 특징이라고도 할 수 있다.
Client-Server Model을 통해 아키텍처를 단순화시키고 작은 단위로 분리 (decouple)함으로써, 각 Client, Server 파트가 독립적으로 개선될 수 있도록 한다.
Client-Server Model:
서비스 요청자 'Client'와 서비스 자원의 제공자 'Server'간에 작업을 분리해주는 분산 애플리케이션 구조
ref. Client-Server Model
URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일. 즉, 일관적으로 인터페이스가 분리되어야 하며 4가지 아키텍처 제약조건이 있다.
리소스 식별: request 내에 기술된 리소스를 '균일한 리소스 식별자 (e.g. URI)'를 사용하여 식별할 수 있어야 한다.
표현을 통한 리소스 조작: Client가 가지고 있는 리소스 표현에는 리소스를 삭제/수정하는데 필요한 데이터가 들어있음.
자체 설명 메시지: Server는 Client가 리소스를 적절하게 사용할 수 있는 방법에 대한 metadata가 포함된 명확한 message를 전송하며, message는 Client가 이해할 수 있는 모든 정보를 포함한다.
애플리케이션 상태 엔진으로서의 하이퍼미디어: hypermedia는 클라이언트가 다른 리소스를 찾을 수 있도록 각 응답에 대한 링크 사용이 필요함. REST에서 hypermedia는 모든 인터랙션에 사용됨.
각 request 간 Client의 context가 Server에 저장되어서는 안된다.
(-> context는 Server에 요청을 보낼 때 함께 전송되는 모든 필요한 정보를 의미하며, 인증정보
, 세션 상태
, 요청 매개변수
, 상태 정보
, etc.가 포함된다.)
즉, Stateless protocol에 의해 수신자 (receiver 또는 Client)가 이전 요청의 sessions 상태를 유지해서는 안된다.
각 응답에는 캐시 가능 여부와 응답을 캐시할 수 있는 기간을 알려주는 정보가 있어야한다. 캐시가 가능한 경우, client는 server에 동일한 request에 대해 해당 response 데이터를 재사용할 수 있다. 이는 성능과 가용성을 개선하는 데 도움이 된다.
REST는 HTTP을 기반으로 하기에, Client는 response를 캐싱할 수 있어야 한다.
ref. Cacheable
장점: 잘 관리된 캐싱은 Client-Server 간 인터랙션을 부분적 또는 완전히 제거하여 인터랙션의 평균 지연시간을 줄여 효율성, 확장성 및 사용자가 인식하는 퍼포먼스를 향상시킬 수 있음.
단점: cache 내의 오래된 데이터가 Server에 직접 요청을 보냈을때, 얻었을 데이터와 크게 다르다면 cache가 신뢰성 (안정성)을 저하시킬 수 있다.
Client는 일반적으로 Server에 직접 연결되었는지, 아니면 중간 서버 (intermediary, 중간매체)를 통해 연결되었는지 알 수 없다.
즉, REST 서버는 다중 계층으로 구성될 수 있다.
중간매체에는 proxy나 gateway 같은 네트워크 기반의 중개 역할을 하는 장치나 소프트웨어를 말하며, 이는 load balancing 기능이나 공유 캐시 기능을 제공함으로써, 시스템 규모 확장성을 향상시키는데 유용하다.
(-> 구조상에 유연성을 둘 수 있음)
Server가 제공하는 자바 애플릿이나 스크립트를 통해 Client가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다. 이는 선택사항이다.
REST API는 HTTP request를 통해 통신하고, 데이터 생성, 읽기, 업데이트 및 삭제 기능을 수행함.
데이터 생성, 읽기, 업데이트, 삭제 작업을 CRUD 작업이라고 함
RESTful API 호출에 대한 일반적인 단계는 아래와 같다.
Client가 Server에 request를 전송한다. Client가 API 문서에 따라 Server가 이해하는 방식으로 request 형식을 지정한다.
Server가 Client를 인증하고 해당 request를 수행할 수 있는 권한이 Client에 있는지 확인한다.
Server가 request를 수신하고 내부적으로 처리한다.
Server가 Client에 response를 반환한다. response에는 request가 성공했는지 여부를 Client에게 알려주는 정보가 포함되며, Client가 요청한 모든 정보도 포함된다.
RESTful API는 아래의 구성요소를 포함하는 요청이 필요하다.
고유 리소스 식별자
: 서버는 고유한 리소스 식별자로 각 리소스를 식별한다. REST 서비스의 경우 URI (Uniform Resource Identifier) 를 사용하여 리소스 식별을 수행한다.
HTTP Methods
HTTP Method | Description |
---|---|
GET | GET을 통해 해당 리소스를 조회함. 리소스를 조회하고 해당 도큐먼트에 대한 자세한 정보를 가져온다. (즉, 데이터 조회 (READ)) |
POST | POST를 통해 해당 URI를 요청하면 리소스를 생성함. (즉, 데이터 생성 (CREATE)) |
PUT | PUT을 통해 리소스를 갱신함. (즉, 데이터 업데이트 (UPDATE)) |
DELETE | DELETE를 통해 리소스를 삭제함. (즉, 데이터 삭제 (DELETE)) |
HTTP 헤더
: 요청 헤더는 Client-Server 간에 교환되는 metadata이다.
e.g. 요청 헤더는 요청 및 응답의 형식을 나타내고 요청 상태 등에 대한 정보를 제공한다.
Data: REST API 요청에는 POST, PUT 및 기타 HTTP 메서드가 성공적으로 작동하기 위한 데이터가 포함될 수 있다.
Parameter: REST API 요청에는 수행해야 할 작업에 대한 자세한 정보를 Server에 제공하는 파라미터가 포함될 수 있다.
URI 세부정보를 지정하는 경로 파라미터
리소스에 대한 추가 정보를 요청하는 쿼리 파라미터
Client를 빠르게 인증하는 쿠키 파라미터
REST 원칙에 따라 Server는 아래와 같은 구성요소를 포함해야 한다.
HTTP 응답 상태 코드
Classes | HTTP response status codes | Description |
---|---|---|
[Successful response] | 200 OK | 클라이언트의 요청을 정상적으로 수행 |
201 Created | 클라이언트가 어떠한 리소스 생성을 요청, 해당 리소스가 성공적으로 생성됨 (POST 메서드 성공 응답) | |
[Client error responses] | 400 Bad Request | 서버가 처리할 수 없는 잘못된 요청 |
401 Unauthorized | 클라이언트가 비인증 (unauthenticated) 상태에서 보호된 리소스를 요청했을 때 | |
403 Forbidden | 클라이언트는 리소스에 접근할 권리를 가지고 있지 않음 | |
404 Not Found | 리소스를 찾을 수 없음 | |
405 Method Not Allowed | 서버가 요청한 메서드는 알고 있지만, 제거되었고 사용할 수 없음 | |
[Redirection messages] | 301 (Moved Permanently) | 요청한 리소스의 URI가 변경되었을 때 |
[Server error responses] | 500 Internal Server Error | 서버에 문제가 있을 경우 |
메시지 본문
: response 본문에는 리소스 표현이 포함된다. Server는 요청 헤더에 포함된 내용을 기반으로 적절한 표현 형식을 선택한다. Client는 데이터 작성 방식을 일반 텍스로 정의하는 XML or JSON 형식으로 정보를 요청할 수 있다.
e.g. Client가 John이라는 사람의 이름과 나이를 요청하면 Server는 다음과 같이 JSON 표현을 반환한다.
'{"name":"John","age":30}'
JSON은 가벼우면서 텍스트 기반의 데이터 교환 형식으로, 여러 프로그래밍 언어에서 쉽게 해석이 가능하고 생성할 수 있음.
XML 형식도 사용가능하지만, 더 많은 마크업이 필요하고 더 복잡한 구조를 가지기에 XML보다는 JSON이 더 널리 사용됨.
헤더
: response에는 응답에 대한 header or metadata도 포함된다. 이는 response에 대한 추가 context를 제공하고 서버, 인코딩, 날짜 및 컨텐츠 유형과 같은 정보를 포함한다.
REST API의 설계 원칙을 통해 아래와 같은 이점을 취할수 있다.
: REST API를 구현하는 시스템은 REST가 Client-Server 인터랙션을 최적화하기 때문에 효율적으로 크기 조정할 수 있다. Stateless는 Server가 Client request 정보를 유지할 필요가 없기 때문에 서버 로드를 제거한다. 잘 관리된 캐싱은 일부 Client-Server 인터랙션을 부분적으로 또는 완전히 제거한다. 이러한 모든 기능은 성능을 저하시키는 통신 병목 현상을 일으키지 않으면서 확장성을 지원함.
: RESTful API는 완전한 Client-Server 분리를 지원하고 각 파트는 독립적으로 발전할 수 있도록 다양한 서버 구성 요소를 단순화하고 분리한다. 서버 애플리케이션의 플랫폼 또는 기술 변경은 클라이언트 애플리케이션에 영향을 주지 않는다. 애플리케이션 함수를 계층화하는 기능은 유연성을 더욱 향상시킨다.
e.g. 개발자는 애플리케이션 로직을 다시 구현하지 않고도 DB 계층을 변경할 수 있음.
: REST API는 사용되는 기술과 독립적이다. API 설계에 영향을 주지 않고 다양한 프로그래밍 언어로 클라이언트 및 서버 애플리케이션을 모두 작석할 수 있다. 또한 통신에 영향을 주지 않고 양쪽의 기본 기술을 변경할 수 있다.
Reference