首页 文章

使用POST创建请求,响应代码为200或201,内容为

提问于
浏览
84

假设我编写了一个REST服务,其目的是将新数据项添加到系统中 .

我计划发帖到

http://myhost/serviceX/someResources

假设有效,我应该使用什么样的响应代码?我可以回复什么内容 .

我正在查看definitions的HTTP响应代码并看到这些可能性:

200:返回描述或包含动作结果的实体;

201:表示创建 . 含义*请求已完成并导致创建新资源 . 新创建的资源可以由响应实体中返回的URI引用,具有Location头字段给出的资源的最特定URI . 响应应该包括一个实体,其中包含资源特征和位置的列表,用户或用户代理可以从中选择最合适的资源特征和位置 . 实体格式由Content-Type头字段中给出的媒体类型指定 . *

后者听起来更符合Http规范,但我一点都不清楚

响应应该包括一个包含资源特征和位置列表的实体

手段 .

建议?解释?

7 回答

  • 41

    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和类型是“资源特征和位置” .

  • 17

    我认为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 Entry的成员条目URI的Location头,以及响应主体中该Entry的表示 .

    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>
    

    集合创建和返回的条目可能与客户端发布的条目不匹配 . 服务器可以更改Entry中各种元素的值,例如atom:id,atom:updated和atom:author values,并且可以选择删除或添加其他元素和属性,或者更改元素内容和属性值 .

  • 8

    我们的想法是,响应主体会为您提供一个链接到该事物的页面:

    201 Created 201(已创建)状态代码表示已完成请求并导致创建一个或多个新资源 . 由请求创建的主要资源由响应中的Location头字段标识,或者如果没有收到Location字段,则由有效请求URI标识 .

    这意味着您将在响应标头中包含 Location ,该标头提供您可以在哪里找到新创建的内容的URL:

    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="/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="/a/36373586/12597">here</A> to view it.
    

    并且 ETag s纯粹是任意值 . 当资源发生变化(并且需要更新缓存)时,让它们变得不同是最重要的 . ETag通常是散列(例如SHA2) . 但它可以是数据库 rowversion ,也可以是递增的修订号 . 当事物发生变化时会发生任何变化 .

  • 80

    看看HTTP: Method Definitions: POST .

    POST方法执行的操作可能不会生成可由URI标识的资源 . 在这种情况下,200(OK)或204(No Content)是适当的响应状态,具体取决于响应是否包括描述结果的实体 . 如果在源服务器上创建了资源,则响应应该是201(已创建)并包含描述请求状态的实体,并引用新资源和Location头(请参阅第14.30节) .

  • 1

    简而言之:

    • 200 创建并返回对象时
      创建对象但仅返回其引用(例如ID或链接)时
    • 201
  • -2

    输出实际上取决于所请求的内容类型 . 但是,至少应该放置在Location中创建的资源 . 只是比如Post-Redirect-Get模式 .

    在我的情况下,我将其留空,直到另有要求 . 因为这是使用Response.created()时JAX-RS的行为 .

    但是,请注意,像Angular这样的浏览器和框架不会自动跟踪201 . 我注意到http://www.trajano.net/2013/05/201-created-with-angular-resource/中的行为

  • 25

    我对此的另一个答案是采取务实的方法,让你的REST API contract简单 . 在我的情况下,我重构了我的REST API,以便在不使用JavaScript或XHR,只需简单的HTML表单和链接的情况下使事情更具可测性 .

    因此,为了更具体地解决上面的问题,我只使用返回代码 200 并使返回的消息包含应用程序可以理解的JSON消息 . 根据您的需要,它可能需要新创建的对象的ID,以便Web应用程序可以在另一个调用中获取数据 .

    请注意,在我重构的API Contract 中,POST响应不应包含任何可缓存的数据,因为POST实际上不可缓存,因此将其限制为可以使用GET请求请求和缓存的ID .

相关问题