응답 코드 200 또는 201 및 내용 인 POST로 요청을 작성하십시오.


125

시스템에 새 데이터 항목을 추가하는 것이 목적인 REST 서비스를 작성한다고 가정합니다.

게시 할 계획입니다.

http://myhost/serviceX/someResources

작동한다고 가정하면 어떤 응답 코드를 사용해야합니까? 그리고 어떤 콘텐츠를 반환 할 수 있습니까?

HTTP 응답 코드 의 정의 를 살펴보고 다음과 같은 가능성을 확인했습니다.

200 : 작업의 결과를 설명하거나 포함하는 엔티티를 반환 합니다.

201 : CREATED를 의미합니다. 의미 * 요청이 이행되어 새 리소스가 생성되었습니다. 새로 생성 된 리소스는 Location 헤더 필드에서 제공하는 리소스에 대한 가장 구체적인 URI와 함께 응답의 엔터티에 반환 된 URI로 참조 될 수 있습니다. 응답은 사용자 또는 사용자 에이전트가 가장 적절한 것을 선택할 수있는 자원 특성 및 위치 목록을 포함하는 엔티티를 포함해야합니다 (SHOULD). 엔티티 형식은 Content-Type 헤더 필드에 제공된 미디어 유형에 의해 지정됩니다. *

후자는 Http 사양과 더 일치하게 들리지만, 나는 무엇인지 전혀 명확하지 않습니다.

응답은 자원 특성 및 위치 목록을 포함하는 엔티티를 포함해야합니다 (SHOULD).

방법.

추천? 해석?

답변:


77

아이디어는 응답 본문이 해당 항목으로 연결되는 페이지를 제공한다는 것입니다.

201 생성됨

201 (생성됨) 상태 코드는 요청이 완료되어 하나 이상의 새 리소스가 생성되었음을 나타냅니다. 요청에 의해 생성 된 기본 리소스는 응답의 Location 헤더 필드 또는 수신 된 Location 필드가없는 경우 유효한 요청 URI로 식별됩니다.

즉 , 새로 생성 된 항목을 찾을 수있는 URL을 제공하는 Location응답 헤더에 를 포함 해야합니다 .

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597

응답 본문

그런 다음 응답 본문에 포함해야하는 내용을 계속 언급합니다 .

201 응답 페이로드는 일반적으로 생성 된 리소스를 설명하고 링크합니다.

브라우저를 사용하는 사람의 경우 새로 생성 된 리소스로 이동하기 위해보고 클릭 할 수있는 항목을 제공합니다.

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: text/html

Your answer has been saved! 
Click <A href="https://stackoverflow.com/a/36373586/12597">here</A> to view it.

페이지가 로봇에 의해서만 사용되는 경우 컴퓨터에서 읽을 수있는 응답을 갖는 것이 합리적입니다.

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: application/xml

<createdResources>
   <questionID>1860645</questionID>
   <answerID>36373586</answerID>
   <primary>/a/36373586/12597</primary>
   <additional>
      <resource>http://stackoverflow.com/questions/1860645/create-request-with-post-which-response-codes-200-or-201-and-content/36373586#36373586</resource>
      <resource>http://stackoverflow.com/a/1962757/12597</resource>
   </additional>
</createdResource>

또는 원하는 경우 :

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/36373586/12597
Content-Type: application/json

{ 
   "questionID": 1860645, 
   "answerID": 36373586,
   "primary": "/a/36373586/12597",
   "additional": [
      "http://stackoverflow.com/questions/1860645/create-request-with-post-which-response-codes-200-or-201-and-content/36373586#36373586",
      "http://stackoverflow.com/a/36373586/12597"
   ]
}

응답은 전적으로 귀하에게 달려 있습니다. 그것은 당신이 원하는 것입니다.

캐시 친화적

마지막으로 생성 된 리소스를 미리 캐시 할 수있는 최적화가 있습니다 (이미 콘텐츠가 있으므로 방금 업로드했습니다). 서버는 내가 방금 업로드 한 콘텐츠와 함께 저장할 수있는 날짜 또는 ETag를 반환 할 수 있습니다.

201 응답에서 ETag 및 Last-Modified와 같은 유효성 검사기 헤더 필드의 의미와 목적에 대한 논의는 섹션 7.2 를 참조하십시오 .

HTTP/1.1 201 Created
Date: Sat, 02 Apr 2016 12:22:40 GMT
Location: http://stackoverflow.com/a/23704283/12597
Content-Type: text/html
ETag: JF2CA53BOMQGU5LTOQQGC3RAMV4GC3LQNRSS4
Last-Modified: Sat, 02 Apr 2016 12:22:39 GMT 

Your answer has been saved! 
Click <A href="https://stackoverflow.com/a/36373586/12597">here</A> to view it.

그리고 ETags는 순전히 임의의 값입니다. 리소스가 변경 될 때 (및 캐시를 업데이트해야 할 때) 달라지는 것이 중요합니다. ETag는 일반적으로 해시 (예 : SHA2)입니다. 그러나 데이터베이스 rowversion또는 증가하는 개정 번호 일 수 있습니다. 변할변할 모든 .


지금까지 당신의 반응이 가장 현명한 것 같습니다. 나는 응답의 온톨로지에 대해 약간 불안하지만, 그 외에는 스펙에 대한 가장 성숙한 해석 인 것 같다. 인간 / 기계 출력을 처리하는 가벼운 "반응 형"방법이 있는지 궁금합니다. 하지만 대부분은 "자신의 입력을 캐싱"하는 당신의 제안에 흥미가 있습니다. 내가 아는 대부분의 웹 앱은 1 : 1 버전의 리소스를 만들지 않습니다. 문자열의 대문자를 정규화하는 것과 같은 사소한 일이더라도. 제출 한 버전을 etag가 생성 된 버전으로 취급하는 것이 조금 어리석지 않습니까?
안토니

1
@Anthony, 캐싱 : 일종의 1 : 1 파일 저장 응용 프로그램 일 수 있습니다. 예를 들어 WebDAV PUT 및 POST를 비교하십시오. 처리해야 할 거대한 파일.
kxr

@Anthony ETag를 클라이언트에게 돌려주고 싶다면 그것은 당신에게 달려 있습니다. 클라이언트가 방금 업로드 한 콘텐츠가 저장 한 내용이 아니면 ETag를 반환하지 마십시오. 그것은 당신의 유연성과 선택입니다.
Ian Boyd

응답에 Content-Length가 누락 된 이유는 무엇입니까?
Vinnie Falco

1
@VinnieFalco 이것은 201 응답 코드에 대한 답변입니다. Content-Length는 설명을 위해 생략되었습니다.
Ian Boyd

91

나는 atompub REST API 가 편안한 서비스의 좋은 예 라고 생각 합니다. atompub 사양에서 아래 스 니펫을 참조하세요.

POST /edit/ HTTP/1.1
Host: example.org
User-Agent: Thingio/1.0
Authorization: Basic ZGFmZnk6c2VjZXJldA==
Content-Type: application/atom+xml;type=entry
Content-Length: nnn
Slug: First Post

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2003-12-13T18:30:02Z</updated>
  <author><name>John Doe</name></author>
  <content>Some text.</content>
</entry>

서버는 상태 코드 201을 사용하여 성공적으로 생성되었음을 알립니다. 응답에는 Atom 항목의 구성원 항목 URI를 나타내는 Location 헤더와 응답 본문에 해당 항목의 표현이 포함됩니다.

HTTP/1.1 201 Created
Date: Fri, 7 Oct 2005 17:17:11 GMT
Content-Length: nnn
Content-Type: application/atom+xml;type=entry;charset="utf-8"
Location: http://example.org/edit/first-post.atom
ETag: "c180de84f991g8"  

<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title>Atom-Powered Robots Run Amok</title>
  <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
  <updated>2003-12-13T18:30:02Z</updated>
  <author><name>John Doe</name></author>
  <content>Some text.</content>
  <link rel="edit"
      href="http://example.org/edit/first-post.atom"/>
</entry>

컬렉션에서 생성하고 반환 한 항목은 클라이언트가 게시 한 항목과 일치하지 않을 수 있습니다. 서버는 atom : id, atom : updated 및 atom : author 값과 같은 항목의 다양한 요소 값을 변경할 수 있으며 다른 요소 및 속성을 제거 또는 추가하거나 요소 내용 및 속성 값을 변경하도록 선택할 수 있습니다.


9
자원이 ... 기가 바이트 크기에있는 경우 생성 된 자원을 반환하는 것은 훨씬 약간있을 수 있습니다
토르 Valamo

10
동의합니다! 그것은 필요성의 최적화입니다. 그러나 당신은 그것을 너무 일찍하고 싶지 않습니다. Restful spirits로 디자인하고 필요할 때만 예외를 만드는 것이 중요합니다.
Chandra Patni

3
@ChandraPatni, Atom이 죽었습니다 . 더 나은 예가 필요합니다.
Pacerier

16
Atom은 죽었을 수 있지만 예제의 정신은 여전히 ​​자리 잡고 있습니다.
Ashimema 2015 년

2
201 응답에 대한 나의 원래 해석은 "어이, 당신은 리소스를 만들고 싶었지만 상황에 따라 최종 결과에 관심이 없거나 쓰기 권한이 있지만이 리소스에 대한 읽기 권한이 없습니다. 주 컬렉션으로 돌아 가기 전에 필요한 것은 생성 된 리소스의 URL뿐입니다. 생성 된 증거로 사용할 수 있습니다. " 그 이상은 본질적으로 200 응답처럼 보입니다. RFC가 다른 것을 염두에 두지 않는 한.
안토니

50

간단히 말해서 :

  • 객체 생성 반환 시 200
  • 201 개체가 생성되었지만 참조 만 반환되는 경우 (예 : ID 또는 링크)

이것에 대한 출처?
sudo soul


3
tools.ietf.org/html/rfc7231#section-6.3.1을 읽은 후이 이해에 동의합니다. 어떻게 도착했는지 더 묻고 있었던 것 같습니다. 하지만 이제 내 이해에 ... 200 = 리소스 생성 및 반환 | 201 = 리소스가 생성되고 참조가 반환 됨 | 204 = 리소스가 생성되고 페이로드가 반환되지 않음
sudo soul

34

HTTP : Method Definitions : POST를 확인하십시오 .

POST 메소드에 의해 수행되는 조치로 인해 URI로 식별 할 수있는 자원이 생성되지 않을 수 있습니다. 이 경우 응답에 결과를 설명하는 엔터티가 포함되는지 여부에 따라 200 (OK) 또는 204 (No Content)가 적절한 응답 상태입니다.

자원이 원 서버에 생성 된 경우 응답은 201 (생성됨)이어야하며 요청 상태를 설명하고 새 자원을 참조하는 엔티티와 위치 헤더 (14.30 절 참조)를 포함해야합니다.


18

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.19

콜론으로 구분 된 키-값입니다.

ETag : "xyzzy"

모든 유형의 텍스트 데이터가 될 수 있습니다. 일반적으로 생성 된 항목의 식별자와 함께 JSON 문자열을 포함합니다. 테스트의 용이성만으로도 포함 할 가치가 있습니다.

ETag: "{ id: 1234, uri: 'http://domain.com/comments/1234', type: 'comment' }"

이 예에서 생성 된 항목의 식별자, URI 및 유형은 "자원 특성 및 위치"입니다.


3
ETag 는 리소스 특성 및 위치 목록을 포함 하는 엔티티에 해당합니다 . 귀하의 제안이 훌륭하다는 것을 알 수 있으며 테스트에 대한 귀하의 요점에 매우 동의합니다. 그러나 이것이 "자원 특성 및 위치 목록"에 얼마나 적합한 지 모르겠습니다.
djna

"자원 특성 및 위치 목록"은 제공된 데이터 구조의 내용입니다. 보다 엄격한 구현은 JSON 구조에 리소스 uri 및 생성 된 리소스 유형을 포함하는 것입니다. 대답을 이렇게 조정하겠습니다.
tempire 2009

7
사람들이 배울 수 있도록 문제를 지정하십시오. 그렇지 않으면 댓글이 손을 흔드는 것입니다.
tempire

@SimonGibbs 무슨 문제?
MEMark

2
사양에 따라 엄격하게 정확하지만 매우 특이한 구현 옵션을 권장합니다. 또한 실제로 페이지 상단의 질문에 대답하지 않습니다 (또는 ETag와 엔티티라는 단어를 혼합하여 대답합니다). 43 표의 답이 아마 더 좋을 것입니다.
Simon Gibbs

1

출력은 실제로 요청되는 콘텐츠 유형에 따라 다릅니다. 그러나 최소한 생성 된 리소스는 Location에 넣어야합니다. Post-Redirect-Get 패턴과 같습니다.

제 경우에는 다른 요청이있을 때까지 비워 둡니다. Response.created ()를 사용할 때 JAX-RS의 동작이기 때문입니다.

그러나 Angular와 같은 브라우저와 프레임 워크는 201을 자동으로 따르지 않습니다. 나는 http://www.trajano.net/2013/05/201-created-with-angular-resource/ 의 행동에 주목했습니다 .


-2

이에 대한 또 다른 대답은 실용적인 접근 방식을 취하고 REST API 계약을 단순하게 유지하는 것 입니다. 제 경우에는 JavaScript 또는 XHR, 단순한 HTML 양식 및 링크에 의존하지 않고 작업을 더 테스트 할 수 있도록 REST API를 리팩터링했습니다.

따라서 위의 질문에 대해 더 구체적으로 설명하기 위해 반환 코드를 사용 200하고 반환 된 메시지에 애플리케이션이 이해할 수있는 JSON 메시지가 포함되도록합니다. 필요에 따라 웹 응용 프로그램이 다른 호출에서 데이터를 가져올 수 있도록 새로 생성 된 개체의 ID가 필요할 수 있습니다.

리팩토링 된 API 계약에서 POST 응답은 실제로 캐시 할 수 없으므로 캐시 가능한 데이터를 포함해서는 안되므로 GET 요청을 사용하여 요청하고 캐시 할 수있는 ID로 제한합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.