<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:enterprise.soap.sforce.com">
<soapenv:Header>
<urn:SessionHeader>
<urn:sessionId><b>QwWsHJyTPW.1pd0_jXlNKOSU</b></urn:sessionId>
</urn:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<urn:fieldList><b>Id, Name, Website</b></urn:fieldList>
<urn:sObjectType><b>Account</b></urn:sObjectType>
<!--Zero or more repetitions:-->
<urn:ids><b>001D000000HS2Su</b></urn:ids>
<urn:ids><b>001D000000HRzKD</b></urn:ids>
</urn:retrieve>
</soapenv:Body>
</soapenv:Envelope>
<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="fail">
<err code="[error-code]" msg="[error-message]" />
</rsp>
<?xml version="1.0" encoding="utf-8" ?>
<s:Envelope xmlns:s="http://www.w3.org/2001/06/soap-envelope">
<s:Body>
<s:Fault>
<faultcode>flickr.error.[error-code]</faultcode>
<faultstring>[error-message]</faultstring>
<faultactor>http://www.flickr.com/services/soap/</faultactor>
<details>Please see http://www.flickr.com/services/docs/ for more details</details>
</s:Fault>
</s:Body>
</s:Envelope>
Roy T. Fielding:
Roy T. Fielding:
GET / HTTP/1.1
이 HTTP 요청 메시지는 뭔가 빠져있어서 self-descriptive 하지 못하다.
GET / HTTP/1.1
Host: www.example.org
목적지를 추가하면 이제 self-descriptive
HTTP/1.1 200 OK
[ { "op": "remove", "path": "/a/b/c" } ]
HTTP/1.1 200 OK
Content-Type: application/json
[ { "op": "remove", "path": "/a/b/c" } ]
HTTP/1.1 200 OK
Content-Type: application/json-patch+json
[ { "op": "remove", "path": "/a/b/c" } ]
글 목록 보기
GET /articles
글 쓰기
GET /new-form
글 저장
POST /articles
목록 얻기
GET /articles
환영합니다!
[글 목록 보기]
제목: ...
제목: ...
제목: ...
[글 쓰기]
글이 생성되었습니다
[생성된 글 보기]
제목: ... 본문: ...
[목록 보기]
제목: ____
본문: ____
[글 저장]
생성된 글 보기
GET /articles/10
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head></head>
<body><a href="/test">test</a></body>
</html>
HTTP/1.1 200 OK
Content-Type: application/json
Link: </articles/1>; rel="previous",
</articles/3>; rel="next;
{
"title": "The second article",
"contents": "blah blah..."
}
성공!
하이퍼텍스트를 포함한 self-descriptive한 메시지의 uniform interface를 통해 리소스에 접근하는 API
REST emphasizes evolvability to sustain an uncontrollable system. If you think you have control over the system or aren’t interested in evolvability, don’t waste your time arguing about REST.
-- Roy T. Fielding
시스템 전체를 통제할 수 있다고 생각하거나, 진화에 관심이 없다면, REST에 대해 따지느라 시간을 낭비하지 마라
I am getting frustrated by the number of people calling any HTTP-based interface a REST API. ... Please try to adhere to them or choose some other buzzword for your API.
-- Roy T. Fielding
I am getting frustrated by the number of people calling any HTTP-based interface a REST API. ... Please try to adhere to them or choose some other buzzword for your API.
-- Roy T. Fielding
제발 제약조건을 따르던지 아니면 다른 단어를 써라
흔한 웹 페이지 | HTTP API | |
---|---|---|
Protocol | HTTP | HTTP |
커뮤니케이션 | 사람-기계 | 기계-기계 |
Media Type | HTML | JSON |
HTML | JSON | |
---|---|---|
Hyperlink | 됨 (a 태그 등) | 정의되어있지 않음 |
Self-descriptive | 됨 (HTML 명세) | 불완전* |
* 문법 해석은 가능하지만, 의미를 해석하려면 별도로 문서가 (API 문서 등) 필요하다.
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<body>
<a href="https://todos/1">회사 가기</a>
<a href="https://todos/2">집에 가기</a>
</body>
</html>
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
[
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"}
]
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<body>
<a href="https://todos/1">회사 가기</a>
<a href="https://todos/2">집에 가기</a>
</body>
</html>
1. 응답 메시지의 Content-Type을 보고 media type이 text/html 임을 확인한다.
2. HTTP 명세에 media type은 IANA에 등록되어있다고 하므로, IANA에서 text/html의 설명을 찾는다.
3. IANA에 따르면 text/html의 명세는 http://www.w3.org/TR/html 이므로 링크를 찾아가 명세를 해석한다.
4. 명세에 모든 태그의 해석방법이 구체적으로 나와있으므로 이를 해석하여 문서 저자가 사용자에게 해 주려고 했던 모든 일들을 해줄 수 있다.
SUCCESS
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<body>
<a href="https://example.org/todos/1">회사 가기</a>
<a href="https://example.org/todos/2">집에 가기</a>
</body>
</html>
a 태그를 이용해 표현된 링크를 통해 다음 상태로 전이될 수 있으므로 HATEOAS를 만족한다.
SUCCESS
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
[
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"}
]
FAIL
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
[
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"}
]
다음 상태로 전이할 링크가 없다
FAIL
서버나 클라이언트가 변경되더라도 오고가는 메시지는 언제나 self-descriptive 하므로
언제나 해석이 가능하다.
어디서 어디로 전이가 가능한지 미리 결정되지 않는다. 어떤 상태로 전이가 완료되고 나서야 그 다음 전이될 수 있는 상태가 결정된다.
쉽게 말해서: 링크는 동적으로 변경될 수 있다
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/vnd.todos+json
[
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"}
]
SUCCESS
단점: 매번 media type을 정의해야한다
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://example.org/docs/todos>; rel="profile"
[
{"id": 1, "title": "회사 가기"},
{"id": 2, "title": "집에 가기"}
]
SUCCESS
단점:
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://example.org/docs/todos>; rel="profile"
[
{
"link": "https://example.org/todos/1",
"title": "회사 가기"
},
{
"link": "https://example.org/todos/2",
"title": "집에 가기"
}
]
SUCCESS
단점: 링크를 표현하는 방법을 직접 정의해야한다
data에 다양한 방법으로 하이퍼링크를 표현한다.
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/json
Link: <https://example.org/docs/todos>; rel="profile"
{
"links": {
"todo": "https://example.org/todos/{id}"
},
"data": [{
"id": 1,
"title": "회사 가기"
}, {
"id": 2,
"title": "집에 가기"
}]
]
data에 다양한 방법으로 하이퍼링크를 표현한다.
SUCCESS
단점: 링크를 표현하는 방법을 직접 정의해야한다
data에 다양한 방법으로 하이퍼링크를 표현한다.
JSON으로 하이퍼링크를 표현하는 방법을 정의한 명세들을 활용한다.
SUCCESS
GET /todos HTTP/1.1
Host: example.org
HTTP/1.1 200 OK
Content-Type: application/vnd.api+json
Link: <https://example.org/docs/todos>; rel="profile"
{
"data": [{
"type": "todo",
"id": "1",
"attributes": { "title": "회사 가기" },
"links": { "self": "http://example.com/todos/1" }
}, {
"type": "todo",
"id": "2",
"attributes": { "title": "회사 가기" },
"links": { "self": "http://example.com/todos/2" }
}]
}
단점: 기존 API를 많이 고쳐야한다. (침투적)
POST /todos HTTP/1.1
Content-Type: application/json
{
"title": "점심 약속"
}
HTTP/1.1 204 No Content
Location: /todos/1
Link: </todos/>; rel="collection"
Link, Location 등의 헤더로 링크를 표현한다.
SUCCESS
단점: 정의된 relation만 활용한다면 표현에 한계가 있다.
종류 | 예 |
---|---|
uri | https://toss.im/users/eungjun |
uri reference (absolute) | /users/eungjun |
uri reference (relative) | eungjun |
uri template | /users/{username} |
다 괜찮음