对于失败的验证或无效的重复项,我应该使用哪个状态代码?

发布于 2024-09-10 07:27:39 字数 285 浏览 4 评论 0原文

我正在使用基于 REST 的 API 构建一个应用程序,并且已经为每个请求指定状态代码。

对于验证失败的请求或尝试在数据库中添加重复项的请求,我应该发送什么状态代码?

我浏览过 http://www.w3.org/Protocols/rfc2616/ rfc2616-sec10.html 但它们似乎都不正确。

发送状态代码时有常见的做法吗?

I am building an application with a REST-based API and have come to the point where I am specifying status codes for each requests.

What status code should i send for requests failing validation or where a request is trying to add a duplicate in my database?

I've looked through http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html but none of them seems right.

Is there a common practice when sending status codes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

萌逼全场 2024-09-17 07:27:39

对于输入验证失败: 400 Bad Request + 您的可选描述。 “RESTful Web Services”一书中建议了这一点。
对于双重提交:409 冲突


6 月更新2014

相关规范曾经是RFC2616,其中给出了400的使用(错误的请求)相当狭隘地作为

由于语法错误,服务器无法理解该请求

因此可能有人认为它不适合语义错误。但现在不再是了;自 2014 年 6 月起,相关标准 RFC 7231 取代了之前的 RFC2616,给出了使用400(错误请求) 更广泛地称为

服务器不能或
由于被认为是的原因,将不会处理该请求
客户端错误

For input validation failure: 400 Bad Request + your optional description. This is suggested in the book "RESTful Web Services".
For double submit: 409 Conflict


Update June 2014

The relevant specification used to be RFC2616, which gave the use of 400 (Bad Request) rather narrowly as

The request could not be understood by the server due to malformed syntax

So it might have been argued that it was inappropriate for semantic errors. But not any more; since June 2014 the relevant standard RFC 7231, which supersedes the previous RFC2616, gives the use of 400 (Bad Request) more broadly as

the server cannot or
will not process the request due to something that is perceived to be
a client error

香橙ぽ 2024-09-17 07:27:39

我推荐状态代码 422,“无法处理的实体”

11.2。 422 无法处理的实体

422(不可处理的实体)状态代码意味着服务器理解请求实体的内容类型(因此 415(不支持的媒体类型)状态代码是不合适的),并且请求实体的语法是正确的(因此 400 (错误请求)状态代码不合适)但无法处理所包含的指令。例如,如果 XML 请求主体包含格式正确(即语法正确)但语义错误的 XML 指令,则可能会出现此错误情况。

I recommend status code 422, "Unprocessable Entity".

11.2. 422 Unprocessable Entity

The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.

眼眸里的那抹悲凉 2024-09-17 07:27:39
  • 验证失败:403 Forbidden(“服务器理解该请求,但拒绝履行它”)。与流行的观点相反,RFC2616 并没有说“403 仅用于失败的身份验证”,而是“403:我知道你想要什么,但我不会那样做”。该情况可能是也可能不是由身份验证引起的。
  • 尝试添加重复项:409 冲突(“由于与资源的当前状态冲突,请求无法完成。”)

您绝对应该在响应标头和/或正文中给出更详细的解释(例如,使用自定义标头 - X-Status-Reason:验证失败)。

  • Failed validation: 403 Forbidden ("The server understood the request, but is refusing to fulfill it"). Contrary to popular opinion, RFC2616 doesn't say "403 is only intended for failed authentication", but "403: I know what you want, but I won't do that". That condition may or may not be due to authentication.
  • Trying to add a duplicate: 409 Conflict ("The request could not be completed due to a conflict with the current state of the resource.")

You should definitely give a more detailed explanation in the response headers and/or body (e.g. with a custom header - X-Status-Reason: Validation failed).

梦途 2024-09-17 07:27:39

200,300,400,500都非常通用。如果你想要通用的,400就可以了。

422 被越来越多的 API 使用,甚至被 Rails 开箱即用。

无论您为 API 选择哪种状态代码,都会有人不同意。但我更喜欢 422,因为我认为“400 + 文本状态”太笼统。此外,您没有利用 JSON-ready 解析器;相比之下,带有 JSON 响应的 422 非常明确,可以传达大量错误信息。

说到 JSON 响应,我倾向于标准化这种情况下的 Rails 错误响应,即:

{
    "errors" :
    { 
        "arg1" : ["error msg 1", "error msg 2", ...]
        "arg2" : ["error msg 1", "error msg 2", ...]
    }
}

这种格式非常适合表单验证,我认为就“错误报告丰富性”而言,这是需要支持的最复杂的情​​况。如果您的错误结构是这样的,它可能会满足您所有的错误报告需求。

200,300, 400, 500 are all very generic. If you want generic, 400 is OK.

422 is used by an increasing number of APIs, and is even used by Rails out of the box.

No matter which status code you pick for your API, someone will disagree. But I prefer 422 because I think of '400 + text status' as too generic. Also, you aren't taking advantage of a JSON-ready parser; in contrast, a 422 with a JSON response is very explicit, and a great deal of error information can be conveyed.

Speaking of JSON response, I tend to standardize on the Rails error response for this case, which is:

{
    "errors" :
    { 
        "arg1" : ["error msg 1", "error msg 2", ...]
        "arg2" : ["error msg 1", "error msg 2", ...]
    }
}

This format is perfect for form validation, which I consider the most complex case to support in terms of 'error reporting richness'. If your error structure is this, it will likely handle all your error reporting needs.

椵侞 2024-09-17 07:27:39

数据库中的重复项应为 409 CONFLICT

我建议使用 422 UNPROCESSABLE ENTITY 来处理验证错误。

我在此处提供了 4xx 代码的详细说明。

A duplicate in the database should be a 409 CONFLICT.

I recommend using 422 UNPROCESSABLE ENTITY for validation errors.

I give a longer explanation of 4xx codes here.

爱人如己 2024-09-17 07:27:39

200

呃...(309, 400, 403, 409, 415, 422)...很多答案试图猜测、争论和标准化的最佳返回代码HTTP 请求成功,但 REST 调用失败

混合使用 HTTP 状态代码和 REST 状态代码是错误

然而,我看到许多实现混合了它们,许多开发人员可能不同意我的观点。

HTTP 返回码与 HTTP 请求 本身相关。 REST 调用是使用超文本传输​​协议请求完成的,它的工作级别低于调用的 REST 方法本身。 REST 是一种概念/方法,其输出是业务/逻辑结果,而HTTP 结果代码是传输结果。

例如,当您调用 /users/ 时返回“404 Not found”会令人困惑,因为它可能意味着:

  • URI 错误 (HTTP)
  • 未找到用户 (REST)

“403 Forbidden/Access Denied”可能意味着:

  • 需要特殊权限。浏览器可以通过询问用户/密码来处理它。 (HTTP)
  • 服务器上配置的访问权限错误。 (HTTP)
  • 您需要进行身份验证 (REST)

并且列表可能会继续显示“500 服务器错误”(Apache/Nginx HTTP 引发的错误或 REST 中的业务约束错误)或其他 HTTP 错误等...

从代码中,很难理解失败原因是什么,是 HTTP(传输)失败还是 REST(逻辑)失败

如果 HTTP 请求在物理上成功执行,则无论记录如何,它都应该始终返回 200 代码。 (s) 是否找到。因为 找到 URI 资源并由 HTTP 服务器处理。是的,它可能会返回一个空集,其中包含 200 作为 HTTP。结果,对吗?

您可以返回 200 HTTP 代码,并带有一些选项:

  • 如果出现问题,JSON 结果中的“错误”对象
  • 如果没有找到记录,则为空 JSON 数组/对象
  • 布尔结果/成功标志与之前的选项相结合此外

,一些互联网提供商可能会拦截您的请求并返回 404 HTTP 代码,这并不意味着找不到您的数据,而是在传输级别出现问题。

来自 Wiki

2004 年 7 月,英国电信提供商 BT 集团部署了 Cleanfeed
内容拦截系统,它会向任何请求返回 404 错误
被 Internet Watch 识别为潜在非法的内容
基础。其他 ISP 在同一情况下返回 HTTP 403“禁止”错误
情况。使用假 404 错误作为手段的做法
泰国和突尼斯也有隐瞒审查制度的报道。在
突尼斯在 2011 年革命之前审查制度很严厉,
人们开始意识到假 404 错误的本质并创建了
一个名为“Ammar 404”的虚构人物,代表“看不见的东西”
审查员”。

为什么不简单地回答这样的问题?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

Google 总是在其地理编码 API 中返回 200 作为状态代码,即使请求在逻辑上失败:https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

对于成功的 HTTP 请求,Facebook 始终返回 200,即使 REST 请求失败: https://developers.facebook.com/docs/graph -api/using-graph-api/error-handling

很简单,HTTP 状态代码是针对 HTTP 请求的,定义您的状态代码。

200

Ugh... (309, 400, 403, 409, 415, 422)... a lot of answers trying to guess, argue and standardize what is the best return code for a successful HTTP request but a failed REST call.

It is wrong to mix HTTP status codes and REST status codes.

However, I saw many implementations mixing them, and many developers may not agree with me.

HTTP return codes are related to the HTTP Request itself. A REST call is done using a Hypertext Transfer Protocol request and it works at a lower level than invoked REST method itself. REST is a concept/approach, and its output is a business/logical result, while HTTP result code is a transport one.

For example, returning "404 Not found" when you call /users/ is confuse, because it may mean:

  • URI is wrong (HTTP)
  • No users are found (REST)

"403 Forbidden/Access Denied" may mean:

  • Special permission needed. Browsers can handle it by asking the user/password. (HTTP)
  • Wrong access permissions configured on the server. (HTTP)
  • You need to be authenticated (REST)

And the list may continue with '500 Server error" (an Apache/Nginx HTTP thrown error or a business constraint error in REST) or other HTTP errors etc...

From the code, it's hard to understand what was the failure reason, a HTTP (transport) failure or a REST (logical) failure.

If the HTTP request physically was performed successfully it should always return 200 code, regardless is the record(s) found or not. Because URI resource is found and was handled by the HTTP server. Yes, it may return an empty set. Is it possible to receive an empty web-page with 200 as HTTP result, right?

Instead of this you may return 200 HTTP code with some options:

  • "error" object in JSON result if something goes wrong
  • Empty JSON array/object if no record found
  • A bool result/success flag in combination with previous options for a better handling.

Also, some internet providers may intercept your requests and return you a 404 HTTP code. This does not means that your data are not found, but it's something wrong at transport level.

From Wiki:

In July 2004, the UK telecom provider BT Group deployed the Cleanfeed
content blocking system, which returns a 404 error to any request for
content identified as potentially illegal by the Internet Watch
Foundation. Other ISPs return a HTTP 403 "forbidden" error in the same
circumstances. The practice of employing fake 404 errors as a means to
conceal censorship has also been reported in Thailand and Tunisia. In
Tunisia, where censorship was severe before the 2011 revolution,
people became aware of the nature of the fake 404 errors and created
an imaginary character named "Ammar 404" who represents "the invisible
censor".

Why not simply answer with something like this?

{
  "result": false,
  "error": {"code": 102, "message": "Validation failed: Wrong NAME."}
}

Google always returns 200 as status code in their Geocoding API, even if the request logically fails: https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

Facebook always return 200 for successful HTTP requests, even if REST request fails: https://developers.facebook.com/docs/graph-api/using-graph-api/error-handling

It's simple, HTTP status codes are for HTTP requests. REST API is Your, define Your status codes.

不醒的梦 2024-09-17 07:27:39

Ember-Data 的 ActiveRecord 适配器期望从服务器返回 422 UNPROCESSABLE ENTITY。因此,如果您的客户端是用 Ember.js 编写的,则应该使用 422。只有这样 DS.Errors 才会填充返回的错误。 您当然可以将 422 更改为适配器中的任何其他代码

Ember-Data's ActiveRecord adapter expects 422 UNPROCESSABLE ENTITY to be returned from server. So, if you're client is written in Ember.js you should use 422. Only then DS.Errors will be populated with returned errors. You can of course change 422 to any other code in your adapter.

深居我梦 2024-09-17 07:27:39

状态代码 304 未修改 也会对重复请求做出可接受的响应。这类似于使用实体标签处理 If-None-Match 标头。

在我看来,@Piskvor 的答案对于我所认为的原始问题的意图来说是更明显的选择,但我有一个也相关的替代方案。

如果您希望将重复请求视为警告或通知而不是错误,则响应状态代码为 304 Not Modified,并且 Content-Location 标头标识现有资源同样有效。当目的只是为了确保资源存在时,重复请求不会是错误,而是确认。请求并没有错误,只是多余,客户端可以参考现有的资源。

换句话说,请求是好的,但是由于资源已经存在,所以服务器不需要进行任何进一步的处理。

Status Code 304 Not Modified would also make an acceptable response to a duplicate request. This is similar to processing a header of If-None-Match using an entity tag.

In my opinion, @Piskvor's answer is the more obvious choice to what I perceive is the intent of the original question, but I have an alternative that is also relevant.

If you want to treat a duplicate request as a warning or notification rather than as an error, a response status code of 304 Not Modified and Content-Location header identifying the existing resource would be just as valid. When the intent is merely to ensure that a resource exists, a duplicate request would not be an error but a confirmation. The request is not wrong, but is simply redundant, and the client can refer to the existing resource.

In other words, the request is good, but since the resource already exists, the server does not need to perform any further processing.

萤火眠眠 2024-09-17 07:27:39

我得出的结论是尝试遵循这个规则:如果它表明客户端开发人员错误,请使用 400 (错误请求)。否则,假设根本没有客户端验证,如果愚蠢用户输入无效数据,则使用422(不可处理实体)。如果有疑问,请优先选择 422,或者也许使用更容易实现的。

这有助于开发人员知道谁真正犯了错误,无论是他自己还是用户。

我所说的“愚蠢的用户”是指非技术用户。攻击者在这里不重要:如果您担心的话,您一开始就不会使用 HTTP 状态代码。 :)

例如,如果您要根据 JSON 架构验证 JSON 请求正文,则 400 是正确的选择(例如缺少键、关键字不匹配)。但是,如果您希望用户输入有效的电子邮件,那么您应该使用 422 (让我再说一遍,假设没有客户端验证)。

这也有助于更好的分支逻辑。例如,在 REST API 的上下文中,假设您有一个调查响应端点,可能具有 POST 和 PATCH 方法。在这种情况下,如果客户端发送无效的 POST 请求,当状态代码为 422 时,您可能需要将新资源的 URI 发送回 Location 标头中,但不适用于 400

现实世界的例子肯定更复杂,但恕我直言,这应该很有效。

I came to the conclusion to try to follow this rule: If it indicates the client developer error, go with 400 (Bad Request). Otherwise, supposing no client validation at all, if a dumb user is entering invalid data, then use 422 (Unprocessable Entity). If in doubt, prefer 422, or maybe use the one with easier implementation.

This helps the developer to know who actually made the mistake, whether himself or the user.

By a dumb user, I mean non-technical user. An attacker shouldn't matter here: If you were that worried about, you wouldn't use HTTP status codes in the first place. :)

For example, if you're validating a JSON request body against a JSON Schema, 400 is the proper choice (e.g. missing keys, keyword mismatches). However, if you're expecting user to enter a valid email, then you should use 422 (let me say again, suppose there is no client validation).

This can also be helpful in better branching logics. For instance, in the context of a REST API, suppose you have a survey response endpoint, with possible methods of POST and PATCH. In this case, if a client sends an invalid POST request, you might want to send the URI of the new resource back in the Location header for when the status code is 422, but not for 400.

Real world examples are more complicated for sure, but this should work great IMHO.

↘人皮目录ツ 2024-09-17 07:27:39

我想每个人对此都会有不同的看法,因为我们都在不同的上下文中提到过状态代码。但重要的是最广泛接受和了解的东西。 400 被认为是验证错误响应并被接受,而 409 顾名思义是冲突。如果我们说 400 不适合验证错误,因为服务器已经理解了请求,那么想象一下有人问你一个你确实从文字中理解的问题,但你可以回答并说“哦,这是一个无效的问题”或“这确实如此”没有意义”,所以仅仅因为你理解了这些词并不意味着它有意义。否则我们可以整天谈论这个

I think everyone will have different opinion on this because we all have referred to status codes in various contexts. But what is important is whatever is most widely accepted and known. 400 is known and accepted as validation error response and 409 as name suggests is a conflict. If we say 400 is not right for validation error because server has understood the request, then think of someone asking you a question which you do understand from words but you could have responded and said "oh that is an invalid question" or "that does not make sense" so just because you understood the words does not mean it makes sense. Otherwise we can keep talking about this all day

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文