优秀的API设计话题,在很多团队涌现,这些团队正在努力完善他们的API策略。
在之前发布的博客上,我简要的讨论了API设计的重要性。一个设计良好的API应该包含那些好处:你的API应该能提高开发者经验、方便的快捷文档和高可用性。
但优秀的API设计究竟应该怎么做?在这个博客中,我将详细的介绍一些RESTful API的最佳设计。
一个设计良好的API的特点
一般来说,一个有效的API设计遇有以下特点:
- 易于阅读和使用。一个设计良好的API应该很容易被使用,其资源和相关操作能够快速的被使用它的开发人员记忆。
- 难以误用。设计良好的API实现和集成将是个简单的过程,写出错误代码将变得不太可能。没有严格按照API开发指南的终端用户将会得到详实的信息反馈。
- 完整又简洁. 最后,一个完整的API应该具有成熟的应用防止你的数据被泄露。API完整性会随着时间的推移而改变,大多数的API设计人员和开发人员都应在现有基础上逐步构建新的API。这是每一个使用API的工程师或公司都必须坚持的理念。
为说明下面列出的概念, 我会以一个照片分享的应用程序举例。 该应用程序允许用户上传照片, 以拍摄地点和心情标签描述照片特征。
集合,资源及其网址
了解资源和集合
资源是REST概念的基础。 一条资源是一个重要对象,它本身可以被引用。 一条资源含有数据,与其他资源的关系,以及操作方法,以允许访问和处理相关信息。
名词化的URL更好
URL应该是整洁、优雅和简单的,这样开发人员更易在他们的web程序中使用你的产品。 很长且难以理解的URL不仅看起来很糟糕,而且在记录时容易出现错误。所以使用名词应该是很好的。
没有规定让资源名词使用单数或复数,但是在如果是集合的话使用复数无疑很好的。 具有相似的资源和集合分别保持它们的一致性是较好的做法。
REStful APIs包含主要的HTTP方法,其良好的定义和独立的功能能够应对所有资源。这里是RESTful API里常用HTTP方法列表,这些方法定义CRUD如何操作资源和集合。
方法 描述 GET 用于请求检索一个资源 POST 用于创建新资源和子资源 PUT 用于更新已存在的资源 PATCH 用于更新已存在的资源 DELETE 用于删除已存在的资源 (如果你想了解PUT和PATCH的不同,可以到StackOverflow上看看这个.) 良好的反馈对于实现的验证是积极的,错误实现产生的消息可以帮助用户调试和纠正使用产品的不正确方式。对于API, 错误信息是使用API上下文的良好方式之一。
调整你的错误与标准HTTP代码一致。客户端引发的错误应该使用400类型错误,如果是服务端的错误应该使用500类型来响应。 一个对资源操作成功后应该返回一个200类型的响应。
有很多的响应代码。想了解更多, 看看这个REST API教程.
一般来说,使用你的API时有三种可能就结果:
- 客户端应用程序的行为是错误的(客户端错误–4xx响应代码)
- API行为错误 (服务器错误- 5 xx响应代码)
- 客户端和API工作正常 (成功– 2xx响应代码)
成功解决客户使用你的API时遇到的问题将大大改善开发人员使用体验和防止滥用API。 详细描述这些错误,同时保持简明和整洁。在错误消息中提供足够的信息有助于用户解决它们的问题,如果你觉得需要更加详细的信息,最好另写文档并在此处提供链接。
GET 响应例子
一个良好设计的API应该有响应示例,以明白是否成功调用了一个URL。响应示例应该简单、简洁和易于理解的。 一个好的经验法则是:帮助开发人员在5秒内理解一个成功的响应。回到我们的照片分享应用,我们定义了 /users 和 /photos URL。 /users 应该易数组的形式提供所有注册的用户,并且包含用户名称和加入日期属性。
你可以在Swagger(OpenAPI)中使用 API设计工具 来定义你的API,详述如下:
responses: 200: description: Successfully returned information about users schema: type: array items: type: object properties: username: type: "string" example: "kesh92" created_time: type: "dateTime" example: "2010-01-12T05:23:19+0000"
注意数据类型和实例的每个响应项注释,最终用户期望的是一个成功的GET调用。成功响应后最终用户将接收的JSON看起来如下
{ “data”:[ { “Username”:“example_user1”, “created_time":“2013-12-23T05:51:14+0000 ” }, { “username”:“example_user2”, “created_time":“2015-3-19T17:51:15+0000 ” } …. ] }
如果用户调用了这个方法,就应该获得包含上述数据和一个说明正确调用了的200响应状态码。 同样的,,一个不正确的调用应该产生适当的400 或500 响应状态码和其它相关信息,以帮助用户更好地操作。
请求
优雅的处理复杂性
你试图开放的数据包含大量的有利于用户的属性,这些属性描述的基本资源和隔离特定信息,可以通过适当的方法来操作。
一个API应该努力提供完整的信息、数据和资源来帮助开发者以无缝的方式与之整合。
然而, 完整意味着对你的API考虑通用使用情况。可能会有许多这样的关系和属性,单独为他们定义资源不是好的做法。
它可以用于开发者获取在特定位置和特定主题标签中共享的所有照片的信息。 您可能还想要通过将每个 API 调用的结果数限制为 10,以减轻服务器负载。 如果最终用户想要找到波士顿的所有照片,并使用 winter 标签,则请求将是:
GET /photos?location=boston&hashtag=winter&limit=10
注意现在的复杂性如何被简化为一个与查询参数的简单关联。如果您想根据客户的请求提供特定用户的信息,则调用:
GET /users/kesh92
API设计入门
没有一个API设计方法能够一劳永逸解决所有组织的问题。上述的建议仅仅是参考意见和建议,能否采用取决于你的用户情况和需求。
一个API设计至关重要的主要原因是你的API能帮助到终端用户,他们的需求就是贯穿你整个API设计的指明灯。
- 作者:Keshav Vasudevan
- 链接:http://coyee.com/article/11302-good-practices-in-api-design
文章来源:https://coyee.com/article/11302-good-practices-in-api-design#comments