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

资源已存在时的POST HTTP响应代码

  •  664
  • vmj  · 技术社区  · 14 年前

    我正在构建一个允许客户端存储对象的服务器。这些对象在客户端完全构造,并带有对象标识,这些标识在对象的整个生命周期中都是永久的。

    我已经定义了API,以便客户端可以使用PUT创建或修改对象:

    PUT /objects/{id} HTTP/1.1
    ...
    
    {json representation of the object}
    

    {id}是对象id,因此它是请求URI的一部分。

    现在,我还考虑允许客户端使用POST创建对象:

    POST /objects/ HTTP/1.1
    ...
    
    {json representation of the object, including ID}
    

    15 回复  |  直到 4 年前
        1
  •  1208
  •   Community Paul Sweatte    4 年前

    我的感觉是 409 Conflict 不过,最合适的方法当然是在野外很少见到的:

    由于与资源的当前状态冲突,无法完成请求。只有在期望用户能够解决冲突并重新提交请求的情况下,才允许使用此代码。响应主体应该包含足够的信息,以便用户能够识别冲突的来源。理想情况下,响应实体将包含足够的信息,以便用户或用户代理修复问题;但是,这可能不可能,也不是必需的。

        2
  •  122
  •   Andrew    7 年前

    根据 RFC 7231 303见其他 现有资源的表示 .

        3
  •  96
  •   Matilda Smeds Phrogz    5 年前

    就我个人而言,我支持WebDAV扩展 422 Unprocessable Entity

    According to RFC 4918

    这个 422不可处理实体 状态码意味着服务器理解请求实体的内容类型(因此 415 Unsupported Media Type 状态代码是不合适的),并且请求实体的语法是正确的(因此 400 Bad Request

        4
  •  74
  •   Sławomir Lenart chown    4 年前

    都是关于 上下文 ,以及谁负责处理请求中的重复项(服务器或客户端或两者)


    指向副本 ,看4xx:

    为了 隐性的 处理重复项,请看2XX:

    • ...

    如果服务器是 期待回报 ,看3XX:

    • 找到302个
    • 303见其他
    • ...


        5
  •  29
  •   p0lar_bear    9 年前

    可能游戏玩得太晚了,但我在尝试制作restapi时偶然发现了这个语义问题。

    我想你可以用这两种方法中的任何一种来扩展一下Wrikken的答案 409 Conflict 403 Forbidden 根据情况-简而言之,当用户完全无法解决冲突并完成请求时(例如,他们无法发送请求),请使用403错误 DELETE 请求显式删除资源),或者如果可能的话使用409。

    10.4.4 403 Forbidden

    服务器理解该请求,但拒绝执行。 请求方法不是HEAD,服务器希望公开 在实体中的拒绝。如果服务器不希望 此信息可供客户端使用,状态码404(不可用)

    至于 PUT 与。 POST ... 岗位 当用户无法或不应该为资源创建标识符时,应使用创建资源的新实例。

    9.6 PUT

    ...

    POST和PUT请求之间的根本区别是 反映在请求URI的不同含义上。中的URI POST请求标识将处理所附 实体。该资源可能是一个数据接受过程,一个访问的网关 相反,PUT请求中的URI标识了用 请求——用户代理知道URI的用途和 服务器不得尝试将请求应用于其他资源。

    然后自己决定是否重定向

        6
  •  12
  •   Grant Gryczan    4 年前

    422 Unprocessable Entity

    作为反对其他答案的论据,使用- 4xx 错误代码意味着这不是客户机错误,显然是。使用非- 表示客户端错误的错误代码完全没有意义。

    看来 409 Conflict POST 请求,例如,使用一个已经使用的用户名,它实际上与目标资源没有冲突,因为目标资源(您尝试创建的资源)尚未发布。当存储的资源版本和请求的资源版本之间存在冲突时,这是一个专门针对版本控制的错误。这非常有用,例如,当客户端缓存了资源的旧版本,并基于该不正确的版本发送请求时,该版本将不再有条件有效。”在这种情况下,响应表示可能包含有助于根据修订历史合并差异的信息。“使用该用户名创建另一个用户的请求是不可处理的,与版本控制无关。

    作为记录,422也是GitHub在尝试使用已在使用的名称创建存储库时使用的状态代码。

        7
  •  11
  •   Alfonso Tienda    8 年前

    我认为你不应该这样做。

    如您所知,POST用于修改集合,并用于创建新项。因此,如果您发送id(我认为这不是一个好主意),您应该修改集合,即修改项目,但这会让人困惑。

    使用它添加一个项目,没有id。这是最好的做法。

        8
  •  9
  •   alanjds    4 年前

    “302找到”对我来说听起来很合理。以及 RFC 2616 表示除了GET和HEAD之外,它还可以被其他请求响应(这当然包括POST)

    我认为

    更新: 在重读了RFC之后,我仍然认为 “4XX+303已找到”代码应正确。然而 “409冲突”是现有的最佳答案代码 (正如@Wrikken所指出的),可能包括指向现有资源的位置头。

        9
  •  7
  •   Sinaesthetic    7 年前

    我认为剩下的,你只需要对特定系统的行为做出决定,在这种情况下,我认为“正确”的答案应该是这里给出的几个答案之一。如果您想让请求停止并表现为客户端犯了一个需要在继续之前修复的错误,那么使用409。如果冲突真的不是那么重要,并且希望继续请求,那么通过将客户端重定向到找到的实体来进行响应。我认为适当的restapi应该在POST之后重定向(或者至少提供location头)到该资源的GET端点,所以这种行为将提供一致的体验。

    编辑: 还有一点值得注意的是,既然你提供了ID,你应该考虑一个PUT。然后行为很简单:“我不在乎现在有什么,把这个东西放在那里。”意思是,如果没有东西,它会被创建;如果有东西,它会被替换。我认为当服务器管理该ID时,POST更合适。将这两个概念分开基本上告诉您如何处理它(即PUT是幂等的,所以只要有效负载验证,POST就应该始终工作,所以如果ID发生冲突,那么409将描述该冲突)。

        10
  •  5
  •   Abd Abughazaleh    4 年前

    在你的情况下,你可以使用 409 Conflict

    HTTPs 下表中的状态代码

    1信息

    100 Continue
    101 Switching Protocols
    102 Processing
    

    2成功

    200 OK
    201 Created
    202 Accepted
    203 Non-authoritative Information
    204 No Content
    205 Reset Content
    206 Partial Content
    207 Multi-Status
    208 Already Reported
    226 IM Used
    

    3重定向

    300 Multiple Choices
    301 Moved Permanently
    302 Found
    303 See Other
    304 Not Modified
    305 Use Proxy
    307 Temporary Redirect
    308 Permanent Redirect
    

    4客户端错误

    400 Bad Request
    401 Unauthorized
    402 Payment Required
    403 Forbidden
    404 Not Found
    405 Method Not Allowed
    406 Not Acceptable
    407 Proxy Authentication Required
    408 Request Timeout
    409 Conflict
    410 Gone
    411 Length Required
    412 Precondition Failed
    413 Payload Too Large
    414 Request-URI Too Long
    415 Unsupported Media Type
    416 Requested Range Not Satisfiable
    417 Expectation Failed
    418 I’m a teapot
    421 Misdirected Request
    422 Unprocessable Entity
    423 Locked
    424 Failed Dependency
    426 Upgrade Required
    428 Precondition Required
    429 Too Many Requests
    431 Request Header Fields Too Large
    444 Connection Closed Without Response
    451 Unavailable For Legal Reasons
    499 Client Closed Request
    

    500 Internal Server Error
    501 Not Implemented
    502 Bad Gateway
    503 Service Unavailable
    504 Gateway Timeout
    505 HTTP Version Not Supported
    506 Variant Also Negotiates
    507 Insufficient Storage
    508 Loop Detected
    510 Not Extended
    511 Network Authentication Required
    599 Network Connect Timeout Error
    
        11
  •  4
  •   Martin Kersten    9 年前

    另一种可能的治疗方法是使用贴片。补丁被定义为改变内部状态的东西,不限于附加。

    修补程序将通过允许您更新现有项目来解决此问题。请参见: RFC 5789: PATCH

        12
  •  2
  •   Hitin    8 年前

    在检查重复记录的正确代码时偶然发现此问题。

    请原谅我的无知,但我不明白为什么每个人都忽略了代码“300”,它清楚地表示“多项选择”或“模棱两可”

    https://tools.ietf.org/html/rfc7231#section-6.4.1

        13
  •  2
  •   Mohammed Safeer    6 年前

    400 Bad Request

    6.5.1. 400 Bad Request


    400(错误请求)状态代码表示服务器无法或 消息帧或欺骗请求路由)。


    通过考虑这些事实,我们可以得出结论,HTTP状态400是错误的请求。

        14
  •  1
  •   Fernando Ferreira    9 年前

    208怎么样- http://httpstatusdogs.com/208-already-reported ? 这是一种选择吗?

    在我看来,如果唯一的事情是一个重复资源没有错误应该提出。毕竟,客户端和服务器端都没有错误。

        15
  •  1
  •   Phillip Harrington    8 年前

    202接受 ? 这是一个正常的请求(200秒),没有客户端错误(400秒)。

    10 Status Code Definitions :

    “202接受。已接受请求进行处理,但处理尚未完成。“

    ... 因为它不需要完成,因为它已经存在了。客户不知道它已经存在,他们没有做错什么。

    我倾向于抛出一个202,并返回类似的内容得到什么 /{resource}/{id}

        16
  •  0
  •   Manjunath Bhadrannavar    4 年前

    这是用户端故障,属于4xx组。这是正确的答案 https://developers.rebrandly.com/docs/403-already-exists-errors

        17
  •  0
  •   Ayush Gupta    4 年前

    我知道已经很久了,但我会在这里留下一个我认为合适的答案。

    我想最好的办法是 HTTP_306_RESERVED .