代码之家  ›  专栏  ›  技术社区  ›  djna

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

  •  89
  • djna  · 技术社区  · 16 年前

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

    我打算寄到

    http://myhost/serviceX/someResources
    

    假设可以,我应该使用什么响应代码?我可以返回什么内容。

    我在看 definitions HTTP响应代码,并查看以下可能性:

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

    201:意思是创造。意味着*请求已完成,并导致创建新资源。新创建的资源可以由响应实体中返回的URI引用,其中位置头字段为资源提供了最特定的URI。响应应该包括一个包含资源特征和位置列表的实体,用户或用户代理可以从中选择最合适的资源特征和位置。实体格式由“内容类型”标题字段中给定的媒体类型指定。*

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

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

    手段。

    建议?解释?

    7 回复  |  直到 8 年前
        1
  •  8
  •   Tempire    16 年前

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

        2
  •  80
  •   Chandra Patni    16 年前

    我想 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,以及该条目在响应主体中的表示。

    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值,还可以选择删除或添加其他元素和属性,或者更改元素内容和属性值。

        3
  •  48
  •   Ian Boyd    10 年前

    其想法是,响应主体会给您一个链接到该内容的页面:

    201创

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

    这意味着您将包括 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="/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,我可以用刚刚上传的内容存储它:

    Section 7.2 为了讨论验证程序头字段(如etag和last modified)在201响应中的含义和用途。

    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 或递增的修订号。任何会 改变 事情 变化。

        4
  •  26
  •   ma11hew28    11 年前

    退房 HTTP: Method Definitions: POST .

    post方法执行的操作可能不会导致可以由URI标识的资源。在这种情况下,200(确定)或204(无内容)是适当的响应状态,这取决于响应是否包含描述结果的实体。

    如果在源服务器上创建了资源,那么响应应该是201(已创建),并且包含一个描述请求状态并引用新资源的实体,以及一个位置头(参见第14.30节)。

        5
  •  23
  •   Stéphane Bruckert jungledev    8 年前

    几句话:

    • 二百 创建对象时 返回
    • 二百零一 创建对象但只返回其引用(如ID或链接)时
        6
  •  1
  •   Archimedes Trajano    13 年前

    输出实际上取决于所请求的内容类型。但是,您至少应该将创建的资源放在适当的位置。就像post-redirect-get模式。

    在我的情况下,除非另有要求,否则我不填。因为这是jax-rs在使用response.created()时的行为。

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

        7
  •  -2
  •   Archimedes Trajano    11 年前

    我对此的另一个答案是采取务实的态度,保持 REST API contract 简单。在我的例子中,我重构了我的RESTAPI,使事情更具可测试性,而无需使用JavaScript或XHR,只需简单的HTML表单和链接。

    所以更具体地说,我只使用返回码 200 并让返回的消息包含应用程序可以理解的JSON消息。根据需要,它可能需要新创建的对象的ID,以便Web应用程序可以在另一个调用中获取数据。

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