Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 在RESTAPI中使用PUT进行更新时,我是否应该允许发送完整的结构?_Http_Rest_Http Put - Fatal编程技术网

Http 在RESTAPI中使用PUT进行更新时,我是否应该允许发送完整的结构?

Http 在RESTAPI中使用PUT进行更新时,我是否应该允许发送完整的结构?,http,rest,http-put,Http,Rest,Http Put,我正在设计一个RESTAPI,我想知道处理资源更新的推荐方法是什么。更具体地说,我会允许通过资源上的PUT进行更新,但是PUT请求的主体中应该允许什么 始终是资源的完整结构 始终是资源结构的子部分(已更改) 两者的结合 例如,以资源http://example.org/api/v1/dogs/packs/p1。 此资源上的GET将提供以下内容: Request: GET http://example.org/api/v1/dogs/packs/p1 Accept: application/xml

我正在设计一个RESTAPI,我想知道处理资源更新的推荐方法是什么。更具体地说,我会允许通过资源上的
PUT
进行更新,但是
PUT
请求的主体中应该允许什么

  • 始终是资源的完整结构
  • 始终是资源结构的子部分(已更改)
  • 两者的结合
  • 例如,以资源
    http://example.org/api/v1/dogs/packs/p1
    。 此资源上的
    GET
    将提供以下内容:

    Request:
    GET http://example.org/api/v1/dogs/packs/p1
    Accept: application/xml
    
    Response:
    <pack>
      <owner>David</owner>
      <dogs>
        <dog>
          <name>Woofer</name>
          <breed>Basset Hound</breed>
        </dog>
        <dog>
          <name>Mr. Bones</name>
          <breed>Basset Hound</breed>
        </dog>
      </dogs>
    </pack>
    
    请求:
    得到http://example.org/api/v1/dogs/packs/p1
    接受:应用程序/xml
    答复:
    大卫
    低音扬声器
    巴塞特猎犬
    博恩斯先生
    巴塞特猎犬
    
    假设我想将一只狗(嗅探巴塞特猎犬)添加到包中,我会支持以下任一选项:

    Request:
    PUT http://example.org/api/v1/dogs/packs/p1
    <dog>
      <name>Sniffers</name>
      <breed>Basset Hound</breed>
    </dog>
    
    Response:
    HTTP/1.1 200 OK
    
    请求:
    放http://example.org/api/v1/dogs/packs/p1
    嗅探器
    巴塞特猎犬
    答复:
    HTTP/1.1200ok
    

    请求:
    放http://example.org/api/v1/dogs/packs/p1
    大卫
    低音扬声器
    巴塞特猎犬
    博恩斯先生
    巴塞特猎犬
    嗅探器
    巴塞特猎犬
    答复:
    HTTP/1.1200ok
    

    或者两者都有?如果建议通过结构的子部分支持更新,我将如何处理删除(例如当狗死亡时)?通过查询参数?PUT的效果是“替换”。因此,是的,您需要提供一个PUT请求的完整表示

    如果要仅更新部分资源,可以选择以下选项:

    • 定义一个表示 分开放在那里
    • 使用“发布到子资源”并具有 服务器返回303请参阅其他 指向目标的位置标头 主要资源
    • 使用补丁

    在您的情况下,最好将狗作为子资源(包中的狗的集合)并以通常的POST as append方式发布到该子资源中

    是的,始终发送资源的完整表示。否则,你会(根据PUT的常见定义和用法)用这只狗来替换背包

    但是,您可能需要考虑以下内容:

    Request:
    GET http://example.org/api/v1/dogs/packs/p1
    Accept: application/xml
    
    Response:
    <pack>
      <owner>David</owner>
      <dogs>
        <dog>
          <name>Woofer</name>
          <breed>Basset Hound</breed>
        </dog>
        <dog>
          <name>Mr. Bones</name>
          <breed>Basset Hound</breed>
        </dog>
      </dogs>
    </pack>
    
    • 在URL路径之外使用XML名称空间或其他版本控制方法(例如?版本=2)
    • 张贴要添加到/dogs/packs/p1的狗。POST根据定义创建了一个从属资源,以便将狗添加到包中
    • 重新整理一下你的网址。在我看来,你真的需要/dogs/1234、/dogs/1235等等,然后是/packs/p1、/packs/p2。然后,您也可以简单地将
      发布到包中
    请记住,REST要求您正确识别资源。包实际上不是狗的从属资源,每只狗都应该有某种唯一的标识符。然后,在访问/packs/p1/1234时,您可能希望重定向到/dogs/1234。或者,您也可以干脆不使用该URL,尽管您接受将从属资源发布到相应的包中


    我想得越多,POST方法就越有意义。也许你甚至可以为所有的狗提供一个/packs/p1/dogs/资源,与包分开。然后,您可以将所有者信息等内容放入/packs/p1,通过/packs/p1/dogs/(其中应包含指向包中每只狗的URL列表,例如/packs/p1/dogs/1234,请参见),通过发布到/packs/p1/dogs/向包中添加新狗,并通过删除/packs/p1/dogs/1235删除狗。每只狗都可以是完整的表示,甚至可以重定向到/dogs/1234等,或者在这个包的上下文中是不同的狗的表示,但同样有一个指向“完整”狗的链接。这取决于您希望如何在包中表示一只狗,当然这也会影响您实际发布到/packs/p1/dogs/的内容。完整的狗感觉不对劲,应该只是我上面展示的一个ID,可能还有关于与背包关系的额外数据。

    +1很好的答案,包括关于HATEOAS替代方法和提示的建议。好东西。