在REST的API错误的最佳实践(Best Practice for Errors in RESTf

2019-08-17 23:24发布

什么是REST风格的API返回的HTTP状态代码的最佳实践? 我使用Laravel 4我的PHP框架。

在一个错误的情况下,我应该使用

return Response::json('User Exists', 401);

要么

包括标志success

return Response::json([
    'success' => false,
    'data' => 'User Exists'],
    401
);

要么

用200代替4XX,依靠success ,以确定是否有错误

return Response::json([
    'success' => false,
    'data' => 'User Exists'],
    200
);

而在成功的情况下,也没有必要返回任何数据,你还回什么?

PHP API代码

public function getCheckUniqueEmail() {
    // Check if Email already exist in table 'users'
    $uniqueEmail = checkIfEmailExists();

    // Return JSON Response
    if($uniqueEmail) {
        // Validation fail (user exists)
        return Response::json('User Exists', 401);
    } else {
        // Validation success
        // - Return anything?
    }
}

Answer 1:

当你看可用HTTP状态代码的列表 ,你会在某个时刻认识到,有很多人,但单独使用本身也不能真正解释错误。

因此,要回答你的问题,有两个部分。 其一是:如何可以将您的API为传达一个错误的原因,并添加有用信息的API(在大多数情况下是另一个开发者)的用户可以读取并在行动。 您应该添加尽可能多的信息越好,这两个机器可读和人类可读。

另一部分:HTTP状态代码帮助如何能区分某些错误(和成功)状态?

后者的部分实际上是比人们的事情更难。 在有些情况下404是用来告诉“没有发现”明显的情况下。 而500是服务器端的任何错误。

我不会用状态401,除非我真的要允许操作成功,如果不存在HTTP认证证书。 401通常触发了浏览器,这是坏的对话框。

在一个的ressource是独特的和现有的情况下,状态为“409冲突”似乎是适当的。 如果创建一个用户成功,状态为“201创造了”听起来是个不错的主意了。

需要注意的是有很多更多的状态码,其中一些涉及到HTTP协议(如DAV)的扩展部分完全不规范(如状态“420增强你的平静”,从Twitter的API)。 看看http://en.wikipedia.org/wiki/List_of_HTTP_status_codes来了解已使用至今,并决定是否要使用合适的东西你的错误情况。

从我的经验,很容易只需选择一个状态代码,并使用它,但它是很难做到一致,并符合现行标准。

我不会停止但这里只是因为别人可能会抱怨。 :)做的RESTful接口,右边是一个艰巨的任务本身,而是更多的接口存在,更多的经验已经收集。

编辑:

关于版本的:它被认为是不好的做法,把一个版本标记到URL,像这样: example.com/api/v1/stuff它会工作,但它是不是很好。

但是,第一件事情就是:请问你的客户指定他希望得到哪种类型的代表性,即他怎么决定是得到JSON或XML? 答:随着Accept头。 他可以发送Accept: application/json的JSON和Accept: application/xml的XML。 他甚至可以接受多种类型,并且它是服务器来决定什么,然后返回。

除非服务器的设计与资源的一个以上的代表回答(JSON或XML,客户选择),确实没有客户端太多的选择。 但它仍然是有客户端发送至少“应用/ JSON”是他唯一的选择,然后再返回头一件好事Content-type: application/json响应。 这样一来,双方都让自己清楚他们想到对方看到这样的内容是什么。

现在的版本。 如果你把版本到URL,您可以有效地创建不同的资源(v1和v2),但在现实中你只有一个资源(= URL)用不同的方法来访问它。 当在请求和/或在其与当前版本不兼容的响应的表示的参数的断裂变化创建API的新版本必须发生。

所以,当你创建一个使用JSON的API,你不处理的通用JSON。 你处理的具体JSON结构是某种独特的API。 你可以,也许应该表明这一点的Content-type服务器发送。 “卖方”扩展是有这样的: Content-type: application/vnd.IAMVENDOR.MYAPI+json将告诉世界,基本的数据结构是application / JSON的,但它是你的公司和你的API,真正讲述其结构期待。 而这正是该版本的API请求适合: application/vnd.IAMVENDOR.MYAPI-v1+json

因此,而不是把版本的网址,您所期望的客户端发送一个Accept: application/vnd.IAMVENDOR.MYAPI-v1+json标题,你回应Content-type: application/vnd.IAMVENDOR.MYAPI-v1+json也是如此。 这确实改变不了什么了第一个版本,但让我们看到,当第2版进场事态如何发展。

该URL的方式将创建一个完全无关的一套新的资源。 客户端将不知道example.com/api/v2/stuff是相同的资源example.com/api/v1/stuff 。 该客户端可能提供了一些资源与V1 API和他保存这些东西的网址。 他应该如何升级所有这些资源到v2? 资源一点也没有变,他们是一样的,那唯一改变的事情是,他们看在V2不同。

是的,服务器可以通过发送重定向到URL V2通知客户端。 但是,重定向没有信号,该客户端还具有对API的客户端部分升级。

当使用接受的版本标题,资源的URL是所有版本中相同。 客户决定使用两个版本1或2,请求资源,服务器可能会这么好心,仍然回答版本1个请求版本1个的反应,但所有版本2个请求与新的和有光泽的版本2级的响应。

如果服务器无法回答一个版本1的要求,他可以通过发送HTTP状态告诉客户端“406不可接受”(所请求的资源只能根据在请求中的Accept头产生的内容不能接受的。)

客户端可以发送接受两个版本头在内,这使服务器与一个他最喜欢的,即应对智能客户端有可能实现的版本1和2,现在将同时作为接受头,并等待服务器升级从版本1到2服务器将在每一个响应说无论是版本1或2,客户端可以采取相应的行动 - 他并不需要知道服务器版本升级的确切日期。

概括起来:对于有限的,也许内部,使用甚至有一个版本可能是矫枉过正一个非常基本的API。 但是你永远不知道这是否会成为一个真正的一年从现在开始。 它始终是一个很不错的主意,包括版本号为API。 而这样做的最好的地方是,你的API即将使用MIME类型里面。 检查单现有版本应该是微不足道的,但你后来透明升级选项,没有混淆现有的客户。



Answer 2:

我不会用200个状态的一切。 这只是将是混乱的。

jQuery的可以让你来处理不同的响应代码不同,有建于方法已经所以要在你的应用程序使用它们,当你的应用程序的增长,你可以提供API供他人使用过的优势。

编辑:另外,我强烈建议看这个讲Laravel和API开发:

http://kuzemchak.net/blog/entry/laracon-slides-and-video



Answer 3:

有在HTTP状态代码的一些列表Illuminate\Http\Response延伸到Symfony\Component\HttpFoundation\Response 。 您可以使用您的类。

例如:

use Illuminate\Http\Response as LaravelResponse;
...
return Response::json('User Exists', LaravelResponse::HTTP_CONFLICT);

它更具有可读性。



文章来源: Best Practice for Errors in RESTful API