作为一名软件开发人员,我们大多数人在日常开发中都需使用或构建REST APIs
接口。 API
接口是系统间的默认通信方式。亚马逊就是一家在如何有效地使用API
进行通信的最佳示例。
在本文中,我将讨论如何更好地设计RESTful API
以避免一些常见错误。
杰夫·贝佐斯(亚马逊集团董事会主席兼CEO)的要求
你们其中部分人可能知道了杰夫·贝佐斯对亚马逊开发人员的要求。如果你没有机会听到它,以下几点是他对开发人员的重要要求。
所有团队今后只通过接口服务公开他们的数据和功能。
团队之间必须通过这些接口相互通信。
不允许任何其他形式的进程间通信 - 不允许直接链接,不允许直接读取另一个团队的数据,不允许使用共享内存模型,不允许任何后门。唯一允许的通信是通过调用网络服务接口。
使用什么技术并不重要。 HTTP,Corba,Pubsub,自定义协议 - 无所谓。贝佐斯不关心这个。
毫无例外地,所有服务接口必须从设计之初就需考虑如何让其它应用来调用。也就是说,团队必须进行规划和设计,同时向其它的调用开发人员公开其接口。所有必须遵守,没有特例。
任何不这样做的人都会被解雇。
最终,这成为亚马逊成功的关键。亚马逊通过构建可扩展的系统,最终像亚马逊网站服务一样提供接口服务。
设计RESTful API原则
现在让我们了解在设计RESTful API
时应遵循的原则。
保持简单
我们需要确保API
的URL
地址非常简单。例如,如果我们要为产品服务设计API
,则应如下定义:
/products
/products/12345
第一个API接口用于获取所有产品,第二个API用于获取特定产品。
使用名词而不是动词
很多开发人员都会犯这个错误。他们通常忘记用HTTP
方法可以更好地描述API
,并最终在API URL
中使用动词。例如,获取所有产品的API
应为:
/products
而不是如下所示
/getAllProducts
使用正确的HTTP方法
RESTful API支持多种方法来表明我们将使用此API的操作类型。
GET - 获取内容或内容列表。
POST - 创建内容或内容列表。
PUT / PATCH - 更新现有内容或内容集合。
DELETE - 删除现有内容或内容集合。
我们需确保为特定的操作使用正确的HTTP方法。
使用复数
这个话题有点争议。有些人在URL命名上使用复数,而有些人则喜欢使用单数。例如 -
/products
/product
我个人喜欢使用复数,因为它避免了我们在讨论接口是用于获取单个或多个内容时而导致不必要歧义。同时它还可避免引起更多的歧义,比如获取所有内容列表而导致的URL扩展,比如product/all
也许有人不认同这种说法,在这里我唯一的建议就是在开发过程整个项目团队中保持使用统一规则。
参数使用
我们设计API时有时除了传入id
之外还需要更多的信息输入。在这种情况下,我们应尽使用查询参数来设计API。
/products?name=’ABC’
优于/getProductsByName
/products?type=’xyz’
优于 /getProductsByType
通过这种方法您可以避免长URL名字。
使用正确的HTTP返回代码
我们有很多HTTP返回代码。大多数人最终只使用其中两个 200
和500
!这当然不是好习惯。以下是一些常用的HTTP代码。
200 OK - 这是最常用的HTTP代码,用于返回所请求操作成功。
201 CREATED - 当您使用POST方法创建新内容时,可以使用此值。
202 ACCEPTED - 可用于确认服务器接收到请求。
400 BAD REQUEST - 当客户端输入验证失败时,可以使用此值。
401 UNAUTHORIZED / 403 FORBIDDEN-如果用户或系统未被授权执行些请求,则可以使用此值。
404 NOT FOUND-如果您正在请求某个资源在系统中不存在,可以使用此值。
500INTERNAL SERVER ERROR - 永远不应该显示抛出,但如果系统出现故障可使用此值。
502 BAD GATEWAY - 如果服务器收到来自上游服务器的无效响应,则可以使用此值。
版本控制
API的版本控制非常重要。不同的公司使用不同的方式来管理版本。一些使用日期作为版本,而一些则通过参数传入版本号。我最喜欢将版本作为URL的前缀来使用。例如:
/v1/products
/v2/products
因为API会经常变化,所以避免在URL中使用逗号。另外,点符号在URL中也不要使用。比如/v1.2/products
保持向后兼容性始终是一种优秀的好习惯,这样,即使您增加了新API版本,使用者也有足够的时间迁移到新版本上来。
使用分页
当您API接口可能返回大量数据列表是则必须使用分页来处理,如果没有进行合适的负载均衡,调用者会搞瘫我们服务。我们需要始终牢记API设计应该是充分测试和无差错的。
推荐使用limit
和offset
。例如/products?limit=25&offset=50
。同时建议API提供limit
和offset
默认值。
支持多种返回数据格式
选择何种API的响应返回数据格式非常重要。新应用程序应尽可能使用JSON作为响应返回格式,除非您有一个仍需要使用XML作为响应返回数据格式的遗留应用程序。
使用正确的错误信息
保持使用成对的错误ID
和message
是一种好习惯。例如,如果您调用Facebook图形API,如果出现错误,它会返回如下消息:
{
"error": {
"message": "(#803) Some of the aliases you requested do not exist: products",
"type": "OAuthException",
"code": 803,
"fbtrace_id": "FOXX2AhLh80"
}
}
我还看过其它一些应用,它们返回带有错误消息的URL,通过这个URL可获取关于此错误更多信息以及如何处理错误消息的建议。
使用OpenAPI规范
如贵公司希望所有团队都遵守某种原则,这种情况下,可考虑使用OpenAPI规范。 OpenAPI允许您先设计API并以更简单的方式与调用者共享。
结论
很明显,如果你想要更好进行团队沟通,API设计变得极为重要。如果API设计的糟糕,会极大的增加团队沟通和开发成本。所以请尽最大努力设计好,剩下的才是好好地实现接口代码。
谢谢你的阅读
如果您有关于设计API的更好方法,请在评论区分享。