Overview
REST = "REpresentational State Transfer" 네트워크 소프트웨어 아키텍처의 한가지로, 리소스를 정의하고 리소스에 대한 상태를 전송을 표헌하는 전반적인 방법론으로, HTTP 상에서 별로의 전송 계층 없이 리소스를 다루기위한 간단한 인터페이스를 가진다.
예를 들어, 웹 상에서 특정 사용의 주문목록을 조회한다고 했을 때, RESTful은 다음과 같이 표현될 수 있다.
[non-RESTful]
/service?userid=1234&action=orderlist
[RESTful]
/users/1234/Oders
위와 같이 URI 만으로 충분히 그 자체를 서술하고 있으며, 그 기능적 의미가 표현되므로, API 작정시 또는 서비스 구현시 직관성이 뛰어나며, 리소스에 대한 일관된 주소(표현)는 유지보수와 생산성을 동시에 높여준다.
Basic
- REST 아키텍처에 적용되는 6가지 제약조건
REST 의 창시자인 로이 필드의 논문에 제시된 바에 따르면 다음 6가지 제약조건이 REST에 적용된다.
단일 인터페이스(Uniform Interface)
무상태(Stateless)
캐시처리가능(Cacheable)
Client-Server
계층화된 시스템
온디멘드 코드(Code on Demand)
단일 인터페이스(Uniform interface)
Client와 Server 사이의 인터페이스 정의로, 아키텍처를 상호 비종속적이고독립적으로 구현한다.
리소스 기반(Resource-Based)
- URI 를 통하여 리소스를 식별하고 요청한다.
- 리소스 자체는 클라이언트에 반환되는 결과 문서와는 개념적으로 분리된다.
- 서버는 데이터베이스 내부의 자료를 직접 전송하는 대신, 데이터베이스 레코드를 HTML, XML이나 JSON 등의 형식으로 표현한다.
표현을 통한 리소스 조작(Manipulation of Resources through representations)
- 클라이언트가 리소스을 지칭하는 표현을 알고있다면, 이 것으로 서버상의 리소스를 수정하거나, 삭제할 수 있는 충분한 정보를 가진 것
자기서술적 메시지(Self-descriptive Message()
- 각각의 메시지는 그 자체로 해당 메시지를 어떻게 처리해야 할 지에 대한 충분한 정보를 알려주어야 한다.
- 어떤 미디어 파일 타입에 어떤 파서를 사용해야할지 알려주어야 한다.
어플리케이션의 상태를 표현하는 하이퍼미디어(Hypermedia)
- 클라이언트는 Body 또는, query-string 파라미터, 요청 헤드 와 요청 URI를 통해 상태를 전송한다.
- 서비스는 클라이언트에게 상태를 전송할 때, 요청의 Body, response code, response 헤드를 통해 상태를 전송한다.
- 위와 같은 것이 기술적으로 하이퍼미디어(Hypermedia)라 한다.
- 또는 하이퍼텍스트에서의 하이퍼링크를 예로 들을 수 있다.
또한 하이퍼미디어는 필요에 따라, 해당 객체 또는 관련 객체를 참조할 URI링크를 리턴 Body에 포함 할 때도 사용된다.
무 상태(Stateless)
- RESTful에서 무 상태(Statelessness)는 핵심 키로서
- 무 상태란 말은 요청을 처리하는데 필요한 상태는 그 요청 자체에 포함되어 있다는 의미
- 서버로 요청할 모든 정보는 클라이언트가 가진다.
- 상태 값은 URI의 한 부분인, 쿼리-스트링, Body, 혹은 Header를 통해전달
- URI는 리소스에 대한 식별자
- Body에서 리소스의 상태를 포함한다.
- 서버에서 요청에 대한 적절한 처리를 한 다음, 상태 값은 다시 클라이언트에 response Header 와 status 코드를 통해 전달한다.
- 웹 서버 컨테이너에서 제공하는Session 과 비교
- REST에서는 서버는client 에 대한 어떠한상태 정보도 가지고있지 않는다.
- 확장성
- 서버는 사용자 세센을유지하지 않는다.
- 부하분산 용이
캐시처리가능(Cacheable)
- 클라이언트의 response 캐시
- Response는 반드시 명시적으로나, 암시적으로캐시가능 여부를 정의해야 한다.
Client-Server
- 관점분리(separation of concerns)
- 단일 인터페이스는 서버과 클라이언트의 분리
- 클라이언트는 서버의 데이터 저장소, 내부 구조로 부터 독립적이므로, 이식성이 뛰어나다.
- 반면 서버는 사용자 인터페이스, 사용자 상태로부터 분리되어 있으므로, 확장성이 뛰어나다.
계층화된 시스템
- 3층 구조
- Client 는 back-end 서버와 직접적으로 통신하지 않고, 중간 계층이 요청을 중계
- 확정성과 부하분산 용이하고, 보안성 강화
온디멘드 코드(Code on Demand)(선택적)
- 자바 애플릿이나 자바스크립트의 제공을 통해 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다
REST API 정의
- 동작을 나타내는 HTTP의 Verbs
- GET, POST, PUT, DELETE를 통해CURD 행위를 처리
분별력 있는 리소스 명명
- /asp?type=posts&id=23 와 같은 경로보다는/posts/23 과 같이 보다 요청이 하고자 하는 바를 보다 명확하게 한다.
- 적절한 리소스명은 그 이름 자체만으로 풍부한설명이 되므로, 이해력이 된다. 따라서 서술적이고 사용자 친화적인 명칭을 사용하도록 한다
XML 과 JSON
- 기본적으로 JSON를 지원하고, 경우에 따라서는JSON 과 XML 모두 지원하도록 한다.
- 확장자 변경함으로써 .xml 에서 .json 으로 쉽게변경할 수 있게 지원
정의(Definitions)
- 멱등성(Idempotence)
- In computer science, the term idempotent is used more comprehensively to describe an operation that will produce the same results if executed once or multiple times. This may have a different meaning depending on the context in which it is applied. In the case of methods or subroutine calls with side effects, for instance, it means that the modified state remains the same after the first call.
즉, 코드의 재진입성과 유사한 개념으로, RESTful이란 요청을 여러 번 호출하더라도, 동일한 결과를 가져다 주어야 한다.
안전성(Safety)
- GET 요청은 안전적이다. 이 메소스는 정보를 조회는 하나, 결코 서버의 상태를 수정할 수 없다.
- 따라서, GET 과 같은 요청은 읽기전용으로 안전하게 처리되어야 한다.
HTTP 메소드
- GET
- HTTP 정의상 GET 메소드는 리소스로 부터 정보를 읽는다(수정불가)
- GET 메소드는 정상적으로 처리될경우, 응답코드 200과 함께 XML 이나, JSON 리턴
- 예)
GET 메소드는 Idempotence
PUT
- 리소스를 수정할 때 사용
- 경우에 따라, 리소스 ID가 서버가 아닌 클라이언트에 의해 지정된 경우 PUS 메소드로 리소스를 생성할 수 있다.
- 즉, PUT 메소드가 존재하지 않는리소스 ID를 가지고 있는 경우라할 수 있음
예)
- PUT http://www.example.com/customers/12345
- PUT http://www.example.com/customers/12345/orders/98765
- PUT http://www.example.com/buckets/secret_stuff
성공시 200 리턴
만약 리소스 생성인 경우 201 리턴
- 리소스 생성시 Location 헤더에 생성한 리소스ID를 반환한다.
- Location=http://www.example.com/customers/12345
PUT 메소스는 비안전 메소드
POST
- POST 메소드는 새로운 리소스를 생성할 때 사용
- 예)
- 성공시 201 리턴하고, Location 헤더에 생성한리소스 ID를 반환한다.
- POST 메소드는 SAFE 하지도 않고 Idempotent 하지도 않는다.
PUT/POST 리소스 생성
- 일반적으로 POST를 사용
- 그러나, 이미 클라이언트가 생성할 리소스 ID를알고 있거나, 그 책임이 있는 경우 PUT를 사용한다.
DELETE
- 리소스 삭제에 사용
- 예)
삭제 성공시 200리턴
실패시 204(NO CONTENT) 반환
Idempotent 메소드(삭제한 리소스에 대해 다시 삭제 하도라도 동일)이나,
존재하지 않는 리소스를 삭제시에는 404(NOT FOUND) 반환
HTTP 메소드 리턴값
리소스 명명(Resource Naming)
- URI 즉, 리소스 명명은 좋은 API를 만드는데 있어, 매우 중요
- RESTful이란 결국 단순히 URI의 집합을 말하여, 이런URI를 HTTP를 통해 호출하고, JSON 이나, xml 형태로 리소스를 표현한 것이라 할 수 있다.
명사를 사용하여 리소스명을 표현하고, 동사는 행위(action)로 표현한다.
예)
- Users of the system.
- Courses in which a student is enrolled.
- A user's timeline of posts.
- The users that follow another user.
- An article about horseback riding.
사용자 관점에서 명명
Resource URI Examples
To insert (create) a new customer in the system, we might use:
POST http://www.example.com/customers
To read a customer with Customer ID# 33245:
GET http://www.example.com/customers/33245
The same URI would be used for PUT and DELETE, to update and delete, respectively.
Here are proposed URIs for products:
POST http://www.example.com/products
for creating a new product
GET|PUT|DELETE http://www.example.com/products/66432
for reading, updating, deleting product 66432, respectively.
다음 URI가 의미하는 바는 무엇일까?
POST http://www.example.com/customers/33245/orders
GET http://www.example.com/customers/33245/orders
POSThttp://www.example.com/customers/33245/orders/8769/lineitems
GEThttp://www.example.com/customers/33245/orders/8769/lineitems/1
리소스 명명 안티패턴(Resource Naming Anti-Patterns)
- 적합하지 않는 RESTful 리소스 URI
- 단 하나의 URI로 서비스 인터페이스를 만들어, query-string으로 요청의 동작을 처리하는 경우
GET http://api.example.com/services?op=update_customer&id=12345&format=json --> poor
사용자 업데이트 URI
GET http://api.example.com/update_customer/12345
GET http://api.example.com/customers/12345/update
복수명칭(Pluralization)
- 리소스 명에 복수를 취할 것인가, 아니면 단수를 취할 것인가?
리소스는 보통 집합을 나타내므로, 복수를 사용
- GET http://www.example.com/customers/33245/orders/8769/lineitems/1
- POST http://www.example.com/customers
- GET|PUT|DELETE http://www.example.com/customers/{id}
경우에 따라서, 복수 개념이 없이 단 하나의 리소스임이 명확한 경우 단수를 사용
- GET|PUT|DELETEhttp://www.example.com/configuration
- 사용자 마다, 환경 구성 값은 단 한개
- GET|PUT|DELETEhttp://www.example.com/customers/12345/configuration
리턴 문서포맷(Returing Representations)
- 리턴 문서는 JSON, XML
- GET http://www.example.com/customers.xml
- Xml 포맷으로 반환
- GET http://www.example.com/customers/12345
- 기본값이 생략된 경우json 포맷사용
- GET http://www.example.com/customers/12345.json
- Json 포맷임을 명시
- 반환 문서 포맷이 지원되지 않을경우 404 오류 리턴
링크 포맷(Link Format) 권장
HTTP/1.1 201 CREATED
Status: 201 Connection: close
Content-Type: application/json; charset=utf-8
Location: http://api.example.com/users/12346
GET 요청 예
{“data”:[{“user_id”:”42”, “name”:”Bob”, “links”:[{“rel”:”self”, “href”:”http://api.example.com/users/42”}]}, {“user_id”:”22”, “name”:”Frank”, “links”: [{“rel”:”self”, “href”:”http://api.example.com/users/22”}]}, {“user_id”:”125”, “name”: “Sally”, “links”:[{“rel”:”self”, “href”:”http://api.example.com/users/125”}]}]}
{"code":200,"status":"success","data": {"lacksTOS":false,"invalidCredentials":false,"authToken":"4ee683baa2a3332c3c86026d"}}
{"code":401,"status":"error","message":"token is invalid","data":"UnauthorizedException"}
<response>
<code>200</code>
<status>success</status>
<data class="AuthenticationResult">
<lacksTOS>false</lacksTOS>
<invalidCredentials>false</invalidCredentials>
<authToken>1.0|idm|idm|4ee683baa2a3332c3c86026d</authToken>
</data>
</response>
쿼리, 필터, 페이징처리
- 결과값 제한
- Limiting via the Range Header
HTTP 헤더에 제한값 설정
Range: items=0-24
Limiting via Query-String Parameters
Range-Based Responses
the server should respond with a Content-Range header to indicate how many items are being returned and how many total items exist yet to be retrieved:
Content-Range: items 0-24/66
Content-Range: items 40-65/66
Content-Range: items 40-65/*
Pagination
Via query-string parameters, this would be equivalent to:
GET ...?offset=25&limit=25
- Range: items=25-49
- Content-Range: 25-49/66 와 동일
For example, to retrieve up to 20 remarks around a given timestamp:
GET http://www.example.com/remarks/home_timeline?after=<timestamp>
Range: items=0-19
GET http://www.example.com/remarks/home_timeline?before=<timestamp>
Range: items=0-19
Equivalently, using query-string parameters:
GET http://www.example.com/remarks/home_timeline?after=<timestamp>&offset=0&limit=20
GET http://www.example.com/remarks/home_timeline?before=<timestamp>&offset=0&limit=20
Filtering
Sorting
Service Versioning
- Support Versioning via Content Negotiation
어플리케이션 수정 또는 요구사항 변경 등, 다양한 이유로 인해, 버저닝이필요
버전이 지정되지 않은 경우 기본 버전
지원되지 않는 버전요청시
더 이상 지원되지 않는 버전 요청시
Date/Time Handling
- Date/Time Serialization In Body Content
- ISO 8601 time point format is a good solution, using the fully-enhanced format that includes hours, minutes, seconds and a decimal fraction of seconds (e.g. yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
https://github.com/tfredrich/DateAdapterJ
ISO8601 Timepoints are:
- Securing process
- OAuth2 권장
전송 보안(Transport Security)
- 모든 인증에 반드시 SSL사용
- OAuth2는 서버 권한처리 와 access token 인증에 TLS요구
- HTTP와 HTTPS 사이의 전환은 보안상 취약하므로 항상 TLS 통신 사용
권한처리(Authorization)
Application Security
Caching and Scalability
The ETag Header
The ETag header is useful for validating the freshness of cached representations
The value for the ETag header can be as simple as a hash of the underlying domain object (e.g. Object.hashcode() in Java)
It is recommended to return an ETag header for each GET (read) operation
'프로그래밍 > ETC...' 카테고리의 다른 글
HTTP 서버 응답 코드 (Response Code) 정리 (0) | 2018.07.27 |
---|---|
IaaS, PaaS, SaaS란 (0) | 2018.05.23 |
AngularJS React Vue.js (0) | 2018.02.20 |
REST(Representational State Transfer), RESTful 개념 (0) | 2018.02.19 |
코딩 테스트 연습할 곳 (0) | 2018.01.27 |