1일 1커밋🌱
REST
1. REST란?
REST
란 무엇인가? REST는 Representational State Transfer
의 줄임말로, 웹을 위한 네트워크 기반 아키텍처
스타일이다. REST는 Roy T. Fielding이 그의 박사학위 논문 “Architectural Styles and the Design of Network-based Software Architectures” 에서 처음 소개하였다.
흔히 REST라고 하면 자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다.
자원(Resource)의 표현(Representation)
- 자원 : 해당 소프트웨어가 관리하는 모든 것 ex) 문서, 그림, 데이터, 해당 소프트웨어 자체 등
- 자원의 표현 : 그 자원을 표현하기 위한 이름 ex) DB의 학생 정보가 자원일 때, ‘students’를 자원의 표현
상태(정보) 전달
- 데이터가 요청되어지는 시점에서 자원의
상태(정보)
를 전달한다. - JSON 혹은 XML를 통해 데이터를 주고받는 것이 일반적이다.
REST의 구체적인 개념 HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE, 자원의 행위)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.
CRUD Operation
- Create : 생성(POST)
- Read : 조회(GET)
- Update : 수정(PUT)
- Delete : 삭제(DELETE)
- HEAD : header 정보 조회
2. REST 구성
REST는 다음의 구성으로 이루어진다.
- 자원(Resource) - URI
- 행위(Verb) - HTTP METHOD
- 표현(Representations)
3. REST 아키텍처의 특징
1) Client-Server 구조
- 클라이언트-서버 스타일은 사용자 인터페이스에 대한 관심(concern)을 데이터 저장에 대한 관심으로부터 분리함으로써 클라이언트의 이식성과 서버의 규모확장성을 개선한다.
- 자원이 있는 쪽이 Server, 자원을 요청하는 쪽이 Client가 된다.
- REST Server : API를 제공하고 비즈니스 로직 처리 및 저장을 책임진다.
- Client : 사용자 인증이나 context(세션, 로그인 정보)등을 직접 관리하고 책임진다.
2) Stateless
- 클라이언트와 서버의 통신에는 상태가 없어야한다. 모든 요청은 필요한 모든 정보를 담고 있어야한다. 요청 하나만 봐도 바로 뭔지 알 수 있으므로 가시성이 개선되고, task 실패시 복원이 쉬우므로 신뢰성이 개선되며, 상태를 저장할 필요가 없으므로 규모확장성이 개선된다.
- Client의 context를 Server에 저장하지 않는다.
- Server는 각각의 요청을 완전히 별개의 것으로 인식하고 처리한다. 즉, 이전 요청이 다음 요청의 처리에 연관되어서는 안된다.
3) Cacheable
- 캐시가 가능해야한다. 즉 모든 서버 응답은 캐시 가능한지 그렇지 아닌지 알 수 있어야한다. 호율, 규모확장성, 사용자 입장에서의 성능이 개선된다.
- 이는 웹 표준 HTTP 프로토콜을 그대로 사용하므로 웹에서 사용하는 기존의 인프라를 그대로 활용할 수 있는 것이다.
- HTTP 프로토콜 표준에서 사용하는 Last-Modified 태그나 E-Tag를 이용하면 캐싱 구현이 가능하다.
4) Uniform Interface
- 구성요소(클라이언트, 서버 등) 사이의 인터페이스는 균일(uniform)해야한다. 인터페이스를 일반화함으로써, 전체 시스템 아키텍처가 단순해지고, 상호작용의 가시성이 개선되며, 구현과 서비스가 분리되므로 독립적인 진화가 가능해진다. 이 스타일은 다음의 네 제약조건으로 이루어진다.
- identification of resources
- manipulation of resources through representation
- self-descriptive messages
- hypermedia as the engine of application state
5) Layered System
- 계층(hierarchical layers)으로 구성이 가능해야하며, 각 레이어에 속한 구성요소는 인접하지 않은 레이어의 구성요소를 볼 수 없어야한다.
- Client는 REST API Server만 호출한다.
- REST 서버는 다중 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고 PROXY, 게이트웨이 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다.
6) Code-On-Demand (Optional)
- Code-On-Demand가 가능해야한다. 서버가 네트워크를 통해 클라이언트에 프로그램을 전달하면 그 프로그램이 클라이언트에서 실행될 수 있어야한다. (Java applet이나 Javascript 같은 것을 말함) 다만 이 제약조건은 필수는 아니다.
- Server로부터 스크립트를 받아서 Client에서 실행한다.
4. 인터페이스 일관성
다음의 인터페이스 일관성이 잘 지켜졌는지에 따라, REST를 잘 사용했는지 판단을 할 수 있다.
1. 자원의 식별
웹 기반의 REST에서는 리소스 접근을 할 때 URI를 사용한다. https://foo.co.kr/user/100
Resource : user
식별자 : 100
2. 메시지를 통한 리소스 조작
Web에서는 다양한 방식으로 데이터를 전달할 수 있다. 그 중에서 가장 많이 사용하는 방식은 HTML, XML, JSON, TEXT 등이 있다. 이 중에서 어떤 타입의 데이터인지를 알려주기 위해서 HTTP Header 부분에 content-type을 통해서 데이터의 타입을 지정해 줄 수 있다. 또한 리소스 조작을 위해서 데이터 전체를 전달하지 않고, 이를 메시지로 전달한다.
ex) 서버의 user라는 정보의 전화번호를 처음에는 number로 결졍했고, 이 정보를 Client와 주고 받을 때, 그대로 사용하고 있었다면 후에 서버의 resource 변경으로 phone-number로 바뀌게 된다면 Client는 처리를 하지 못하고 에러가 난다. 이러한 부분을 방지하기 위해서, 별도의 메시지의 형태로 데이터를 주고 받으며, client-server가 독립적으로 확장 가능하도록 한다.
3. 자기 서술적 메시지
요청하는 데이터가 어떻게 처리되어야 하는지 충분한 데이터를 포함할 수 있어야 한다. HTTP 기반의 REST에서는 HTTP Method와 Header 정보, 그리고 URI의 포함되는 정보로 표현할 수 있다.
GET : https://foo.co.kr/user/100, 사용자의 정보 요청
POST : https://foo.co.kr/user, 사용자의 정보 생성
PUT : https://foo.co.kr/user, 사용자의 정보 생성 및 수정
DELETE : https://foo.co.kr/user/100, 사용자의 정보 삭제
그 외에 담지 못한 정보들은 URI의 메시지를 통하여 표현한다.
4. 애플리케이션 상태에 대한 엔진으로써 하이퍼미디어
REST API를 개발할 때 단순히 Client 요청에 대한 데이터만 응답해주는 것이 아닌 관련된 리소스에 대한 Link 정보까지 같이 포함되어져야 한다.
이러한 조건들을 잘 갖춘 경우 REST Ful하다고 표현하고, 이를 REST API라고 부른다.
5. REST의 representation이란 무엇인가
“REST의 R은 Resource가 아니라 Representational이다.”
사실 서버가 보내는 것은 리소스가 아니다.
다음과 같은 HTTP GET 요청을 서버에 보내서
GET https://example.org/greeting
Host: example.org
Accept: text/plain, text/html; q=0.9 *; q=0.1
Accept-Language: en, ko; q=0.9, *; q=0.1
“hello”라는 메시지를 응답으로 받았다고 해보자.
HTTP/1.1 200 OK
Content-Length: 6
Date: Sun, 19 Mar 2017 10:20:47 GMT
Last-Modified: Sun, 19 Mar 2017 08:00:00 GMT
Content-Type: text/plain
Content-Language: en
hello
여기서 https://example.org/greeting이라는 uri를 요청해서 “hello”라는 리소스를 응답으로 받은 것이라고 생각할 수 있다. 하지만 사실 “hello”는 리소스가 아니라 representation data
이다.
그 이유는 HTTP의 GET 메서드의 정의를 보면 알 수 있다.
The GET method requests transfer of a current selected representation for the target resource.
GET 메소드는 Target Resource에 대한 현재의 선택된 representation의 전송을 요청하는 것이다.
즉, “hello”자체가 리소스가 아니라 “환영의 의미를 담은 문서”가 리소스인 것이다. 리소스는 HTTP 요청의 대상이 되며 무엇이든 될 수 있다.
그렇다면 representation 이란 무엇인가? 어떤 리소스의 특정 시점의 상태를 담고 있는 정보
이다. 하나의 representation은 representation data와 representation metadata로 구성된다. 위의 예에서는 “hello”가 representation data이고, 헤더의 “Content-Type: text/plain
Content-Language: en”가 representation metadata이다.
“현재” 란 무엇인가? 만약 리소스의 현재 상태가 “hello”가 아닌 “hi”라면 현재 representation은 “hello”가 아닌 “hi”가 될 것이다.
“선택된” 은 무엇인가? 이는 하나의 리소스의 현재 representation이 하나 이상이 될 수 있으며, 그 중 하나가 선택되었음을 의미한다. 다시 헤더의 “Content-Type: text/plain Content-Language: en” 정보를 보면 Contet-Type은 HTML 문서도 될 수 있고, Plain 텍스트도 될 수 있는데 HTML 문서를 위한 사용자를 위해 선택되었고, Content-Language는 한국어 사용자도 될 수 있고, 영어 사용자도 될 수 있는데 영어 사용자를 위해 Content-Language가 선택되었음을 알 수 있다.
그렇다면 선택은 누가 어떻게 하는 것인가?
클라이언트와 서버간의 내용 협상(Content negotitation)
을 통해 선택하며, 선택의 주체는 협상 방법에 따라 다르다.
사전 협상(proactive negotiation)
의 경우는 서버가 선택한다. 클라이언트가 GET 요청에
“Accept-Language: ko” 헤더를 포함시켜 한국어를 선호한다고 밝혔을 때 서버는 가장 절절한 Representation인 “안녕하세요”로 응답할 것이다.
이러한 선택을 “여러 리소스 중 하나가 선택되었다”라고 말할 수 없는 이유는 무엇일까? “안녕하세요”든 “hello”든 모두 uri가 동일하기 때문이다. uri가 동일하다면 같은 리소스이다. 따라서 여러 리소스 중 하나가 선택된 것이 아니다.
그러나 사후 협상(reactive negotiation)
의 경우에는 서버가 uri의 목록으로 된 선택지를 주면 클라이언트가 선택한다. 이 경우는 선택지마다 uri가 각각 다르므로 클라이언트가 리소스들 중 하나를 선택한다고 할 수 있다.
6. 결론
REST는 Representational State Transfer의 약자이다. Transfer는 서버에서 클라이언트로의 웹 페이지 전송을 의미하는 것이다. 사용자가 링크를 클릭하면 브라우저가 보여주는 페이지는 A에서 B로 전송된다. A에서 B로 상태가 변경된 이유는 Representation의 전송을 통해서이다.
결론적으로 REST는 Target Resource에 대한 현재의 선택된 representation의 Transfer를 통한 클라이언트의 State의 변경인 것이다.
참고
- https://datatracker.ietf.org/doc/html/rfc7231#section-3
- https://blog.npcode.com/2017/04/03/rest%EC%9D%98-representation%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80/
- https://blog.npcode.com/2017/03/02/%EB%B0%94%EC%81%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%93%A4%EC%9D%84-%EC%9C%84%ED%95%9C-rest-%EB%85%BC%EB%AC%B8-%EC%9A%94%EC%95%BD/
- https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
- https://meetup.toast.com/posts/92
- 패스트 캠퍼스 : Java/Spring 웹 개발 마스터 초격차 패키지
댓글남기기