REST API 设计
2016-05-28
设计简洁易懂的API对前后端的同学都是极有好处的,对后端同学来说,简洁的设计可以减少本就复杂的API设计及与前端同学交流沟通的成本, 而对前端同学来说,易于理解的API是提高编程效率的手段之一。
规避API设计误区
我们在设计API设计的时候经常忽略掉的一个问题就是API之前缺少关联性。
例如:
如果想获得商品列表, 通过AJAX请求GET /categories
;
如果想获取某个分类中的商品GET /getProductListFromCate?category_id=id
;
如果想获取多个分类中的商品, 要使用GET /productInCategories?values=id_1, id_2,...id_n
;
如果保存商品的描述,要使用POST /product
, 同时在请求总体(body)中添加大量的JSON数据;
可能你已经习惯了这样的API设计,可这样的设计的有些怎么样的缺点呢:
- 不同的请求可能会出现不同的命名约定,有的端点重复了的get方法(命名里get 和 GET请求的重复),有的端点使用驼峰式,有的端点使用的是连字符, 有的使用下划线。总之, 这样导致网站可能出现风格不一致的API,即使团队严格保存一致的风格,不同的团队之间的习惯不同也会使网络上的url出现不一致的重复。
- 不知道何时该使用HTTP方法(HEAD,GET,POST,PUT,PATCH或者DELETE),于是只使用了GET/POST。
- 没有明确区分查询参数与请求主体,GET/POST的混用,GET请求用于修改,如
GET /saveProduct?id=12
。这样的用法违背GET与POST的原来的分工。我们可以用简洁的POST /product
来代替。 - API的一致性。
REST
具象状态传输(英文:Representational State Transfer,简称REST)是Roy Thomas Fielding博士于2000年在他的博士论文 “Architectural Styles and the Design of Network-based Software Architectures” 中提出来的一种万维网软件架构风格。 需要注意的是,REST是设计风格而不是标准。REST通常基于使用HTTP,URI,和XML以及HTML这些现有的广泛流行的协议和标准。
- 资源是由URI来指定。
- 对资源的操作包括获取、创建、修改和删除资源,这些操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法。
- 通过操作资源的表现形式来操作资源。
- 资源的表现形式则是XML或者HTML,取决于读者是机器还是人,是消费web服务的客户软件还是web浏览器。当然也可以是任何其他的格式。
从百科上的定义我们可以看到一个很明显的事实,即资源的重要性。在REST中,资源是一切信息的抽象。请牢记这一点。
基于REST的API设计的通用指导规范
1. 端点的名称
除前缀的域名外的部分
- 全部小写,使用连字符,如
api/verification-tokens
,小写既是出于习惯,也是出于可读性。而连字符既是为了可读性,也是为了对url操作的方便,比如前端要取出第一个词只需要url.split("/")[len-1].split("-")[0]
,或者可以称之为“可编程性”。 - 使用一或两个词描述资源。
- 资源一定要使用复数,使用
api/users
,而不是api/user
。符合语义。
2. HTTP方法与CRUD操作的对应关系
一个极端的例子,如果你的网站有删除的功能,并且使用的是GET方法,那么你的网站将有风险会被爬虫删除网站里的内容。
一些典型的设计
方法 | 端点 | 说明 |
---|---|---|
GET | /products | 获取一系列商品 |
GET | /products/:id | 通过id获取某个商品 |
GET | /products/:id/parts | 获取某个商品的某个部件 |
PUT | /products/:id/parts | 为某个商品添加一个新部件 |
DELETE | /products/:id | 删除某个指定id的商品 |
PUT | /products | 添加一个新商品 |
HEAD | /products/:id | 通过状态码(200 或者 404)判断指定商品是否存在 |
PATCH | /products/:id | 编辑指定id对应的商品 |
POST | /auth/login | 多数其他的应该使用POST方法 |
为API编写文档
- 说明响应的结果
- 演示报告错误的方式
- 概述认证、分页、限流、缓存的工作方式
- 详细说明每个端点、查询这些端点要使用哪个HTTP方法,请求中应该包含的每个数据,以及可能出现的响应字段。
可以学习一下github的api。