跳转至

Restful设计最佳实践

restful要设计得好并不容易,工作中见了太多错误不好的写法,所以我觉着自己可以再写一篇文章总结分享给大家。

使用版本号

/v1/books /v2/books 不使用动词,用 Get / Post / Put / Patch / Delete 代表 获取 / 创建 / 修改(整个) / 修改(部分) / 删除

GET /v1/books 获取书列表 GET /v1/books/1 获取单本书 PUT /v1/books/1 修改整本书 PATCH /v1/books/1 修改书的部分信息 DELETE /v1/books/1 删除书 用复数

/v1/books /v1/books/1 资源附属

GET /v1/users/1/books 获取id为1的用户的所有书 用减号(-)串连单词,如果用驼峰命名会使得url不美观

/v1/fiction-books 这些都是restful接口设计的基本原则,大多数情况下是管用的。但实际上这些基本原则并不能覆盖到所有场景。

所以我们需要对其做一些扩展。

长期的后端框架开发和总结分析我得出了下面几条restful扩展方法:

非增删改查资源操作,使用动词叠加在资源后表示一种资源操作目的

单数化,对确定只有一个结果的资源使用单数

代词,对确定的资源使用代词替换id数字

批量资源操作,使用逗号隔开的数字字符串代表多个资源

即时资源,不保存数据库即时创建即时返回资源

分类隔离,使用前缀分类接口

具体场景举例:

用户登录,注册,修改密码 使用非增删改查资源操作设计(推荐)

POST /v1/user/login POST /v1/user/register POST /v1/user/change-password 使用即时资源设计

POST /v1/token 登录,等同于创建一个token资源 使用基本原则设计

POST /v1/users 注册用户 PATCH /v1/user/password 修改密码

获取用户个人信息 单数化设计(推荐)

GET /v1/user 用单数user代表当前登录用户 GET /v1/user/books 当前登录用户的书 使用代词设计

GET /v1/users/me 保留restful基础的复数格式,用me代指自己,因为请求的时候id是存在header的token之中 GET /v1/users/me/books

生成pdf 使用非增删改查资源操作设计

POST /v1/books/{id}/generate-pdf 将id为1的书生成pdf文件

获取书的作者 假定系统规定,一本书只有一个作者,如果按照基本原则设计,需要做2个接口

调用方需要先调用列表接口拿到作者的id后,再次使用作者id获取作者信息

GET /v1/books/{id}/authors 获取作者列表,拿到author id GET /v1/books/{id}/authors/{aid} 获取作者信息 为了简化调用,可以使用单数化设计,author改为单数代表这本书唯一的作者

GET /v1/books/1/author 附属单数化设计必须明确资源的对应关系是1对1

搜索 使用基本原则设计

GET /v1/books?title=西游记 如果搜索条件多了,使用url query的形式去设计就会出现限制,因为url的长度是有限的,此外url上还需要做一些字符转义的工作。

这个时候可以考虑,使用即时资源设计,改为POST请求

POST /v1/book-searches 即时创建searches资源返回给调用方

批量查询,删除 使用批量资源操作设计

GET /v1/books/1,2,3,5 获取id为 1,2,3,5 的4本书 DETELE /v1/books/1,2,3,5 删除id为 1,2,3,5 的4本书

内部接口,外部接口,测试接口.... 微服务的接口不一定是全对客户端,部分接口可能是做微服务内部调用,也有可能做不同需求调用,这个时候可以在版本号前再加上前缀。

使用分类隔离设计

GET /internal/v1/users/1 内部接口获取用户信息 GET /v1/users/1 外部接口获取用户信息 POST /test/v1/users/1/change-password 测试接口修改密码