RESTFul API 设计最佳实践

8 阅读5分钟

RESTFul API 设计最佳实践

RESTFul

​ REST(Representational State Transfer),表现层状态转移。 它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 表现层是资源的表现层,对于网络中的资源就需要URI(Uniform Resource Identifier)来指向。REST指的是资源的状态变化。

注:RESTFul没有标准。

早期,我们如果需要操作后台数据,往往如下设计URL

http://www.magedu.com/addStudent?name=tom
http://www.magedu.com/student?action=add&name=tom 

如果使用Restful该如何表达呢?

1、协议

使用HTTP或者HTTPS。对外若有安全性要求,可以使用HTTPS。但是内部服务间调用可以使用HTTP或HTTPS。

2、HTTP方法

HTTP请求中的方法表示执行的动作

常用方法(动词)说明
GET获取资源
POST创建新的资源
PUT更新资源
PATCH部分更新资源
DELETE删除资源

3、使用名词

​ URL指向资源,在URL路径的描述中,只需要出现名词,而不要出现动词。动词由HTTP方法提供。 不要单复数混用,建议名词使用复数。 Restful的核心是资源,URL应该指向资源,所以应该是使用名词表达,而不是动词表达。

方法路径说明
GET/posts返回所有文章
GET/posts/10返回id为10的文章
POST/posts创建新的文章
PUT/posts/10更新id为10的文章
DELETE/posts/10删除id为10的文章
PATCH/posts/10部分更新id为10的文章数据

不要出现下面的访问资源的路径 :

/getAllPosts
/addPost
/updatePost
/delPost
上面URL中动作和资源混在一起,不好

GET方法只是获取资源,而不是改变资源状态。改变资源请使用POST、PUT、DELETE等方法。

例如,使用 GET /posts/10 就可以获取资源了,但是却使用 GET /posts/10/del 或 GET /posts/10?action=del ,本意是想删除。但这样不好,GET方法请求只为获取资源,不要改变资源状态。

子资源的访问:

方法路径Endpoint说明
GET/posts/10/authors返回id为10的文章的所有作者
GET/posts/10/authors/4返回id为10的文章的作者id为4的

4、集合功能

一般指的是在返回多行数据的时候,使用查询字符串来过滤数据。

过滤 Filtering

指定过滤条件 GET /posts?tag=python。 上例中,目的就是访问所有帖子,但是只是访问其中的一部分符合条件的帖子。

排序 Sorting

指定排序条件。有很多种设计风格,例如使用+表示asc,-表示desc。GET /posts?sort=+title,-idGET /posts?sort=title_asc,id_desc

分页 Pagination

一般情况下,查询返回的记录数非常多,必须分页。GET /posts?page=5&size=20

5、状态码

​ 使用HTTP响应的状态码表示动作的成功与否。 2XX表示用户请求被服务器端成功的处理;4XX表示用户请求的错误;5XX表示服务器端出错了。

Status Code说明Method说明
200OKGET成功获取资源
201CREATEDPOST、PUT、PATCH成功创建或修改
204NO CONTENTDELETE成功删除资源
400Bad RequestALL请求中有错误,例如:GET时参数有问题、PUT时提交的数据错误等。
401UnauthorizedALL用户未通过认证
403ForbiddenALL有无权限都禁止访问该资源
404Not FoundALL请求的资源不存在
500Internal Server ErrorALL服务器端错误

www.w3.org/Protocols/r…

6、错误处理

在Restful API设计中,错误处理也非常重要。单单从状态码中无法详尽描述错误的信息。

1、返回消息

{
	"error":"User Not Found"
}

2、从错误消息中了解到错误号、错误信息、错误描述等信息。甚至更详细的信息可以通过code查阅文档

{
    "code":10056,
    "message":"Invalid ID",
    "description":"More details":
}

code 为 0 表示无错误。非0表示有错误,message是更详细、更友好的错误描述。

7、版本

​ 在较大项目开发时,由于业务升级,需要对接口调用做出改动,例如请求参数、返回状态码、json数据发生变化等。如果使用同一套接口,在原有接口上直接修改会导致原有调用者调用出问题。解决方法:

  1. 完全兼容原有接口,虽然这样做可以,但是很难做到所有接口的完全兼容设计。实在不行的,老的接口保留不动,建立新的API接口以供调用。但这样增加了接口个数,冗余、繁杂,非常不好
  2. 对已经发布使用的接口规定版本号访问。新增的、改进的、删除的API重新发布新的版本。项目开发时,指定版本和接口即可。老项目可以不必升级到这个新版本。

强烈要求使用版本,版本号使用简单数字,例如v2。

2种风格

api.mm.com/v1/posts/10 这种风格会跨域,适合较大的项目

www.mm.com/api/v1/post…

8、返回结果

方法路径状态码说明
GET/posts200返回所有文章的对象的列表
GET/posts/10200返回id为10的文章对象
POST/posts201创建新的文章并返回这个新创建的对象
PUT/posts/10201更新id为10的文章的文章并返回这个被更新对象
DELETE/posts/10201删除id为10的文章返回一个空对象,或不返回任何对象
PATCH/posts/10204部分更新id为10的文章数据并返回这个被更新对象

返回数据一律采用JSON格式,需要序列化。