API 通用规范

简介: API 通用规范

大家好,我是 17 。

RESTful 是目前最流行的 API 设计规范,用于 Web 数据接口的设计。但是实操中会遇到很多问题。

1. 服务器不支持 PUT,DELETE 方法

有人说加一个头

POST /api/Person/4 HTTP/1.1  
X-HTTP-Method-Override: PUT
复制代码

但实际上,不是加上这个头,服务器就自动支持了,还得进行配置才行。

2. 大家对规范的理解不大一样

比如版本号,有人说直接放 path 里,有人说放参数里,等等。

规范的意义之一是减少沟通成本,既然无法统一,也不大可能通用,那在自己的团队里还不如自己制定一个规范,用着舒服就行了。当然了,自己制定规范的时候,可以参考 RESTful

通用接口规范

路径一律用单数名词,最多两级路径

路径代表资源的位置。既然是位置,当然没有单数复数之分。最多两级是为了简化逻辑。

/article
/fruit
/fruit/apple
复制代码

动作用 method 参数

每个位置的资源都可以进行各种处理。

method 可以是 http 协议中规定的动作: GET、POST、PUT、DELETE,HEAD。虽然还有其它动作,但是为了简化,我们只用这 5 个动作。服务端在执行这些动作时必须要与 http 协议中对这 5 个动作的规定相符。

其它参数

其它用来描述资源的都用参数来表示

/fruit?price=1&color=red
复制代码

命名空间

对于不同的项目,api 的 path 可能会冲突。如果一个 api 需要多个项目通用,可以在最前面多加一级加上命名空间。

/n-market/fruit/apple
复制代码

n-market 就是命名空间,为了便于和后面的 path 区分 以 n- 开头。

实现规范

在实现层面有非常多的选择,不方便给出适合所有情况的方案。但为了让大家了解本规范,还是决定给出一个供参考的方案。

转发不同命名空间的请求

既然要用一个独立的命名空间,这些 api 应该是一个独立的服务。nginx 直接对请求进行转发。

location /n-market/ {
     proxy_pass http://127.0.0.1:3001/;
  }
复制代码
  1. 把 /n-market/ 开头的请求转发到 3001 端口,并去掉 /n-market/。

比如 请求 /n-market/a/b     3001 接口接收到的请求 为 /a/b

对于服务内部来说,/n-market/ 并不需要,/n-market/ 只是在服务外面用的,用来和其它服务的接口做区分。

除了 get,head,其它的都用 post

一般来说,服务支持 HEAD,GET,POST 三种 method。对于服务器可能不支持的 PUT,DELETE,在客户端直接发送 post 请求。拿 js 举例

let httpMethod = '';
switch (method) {
  case 'HEAD':
  case 'GET':
    httpMethod = method;
    break;
  default:
    httpMethod = 'POST'
    break;
}
复制代码

服务端根据 path 做处理

路径最多有两级,服务端也可以设置两级处理。比如第一级对应一个类,第二级对应一个方法。方法里处理具体的动作。这里有动作有四种,是通过 url 参数传过来的。 head 一般在 nginx 就直接处理了,所以这里只有四种方法。

class Fruite{
  apple() { 
    switch (method) {
      case 'GET':
      case 'GET':
      case 'PUT':
      case 'DELETE':
    }
  }
  banana() { }
}
复制代码

如果路径只有一级,相当于省略后面的方法名,默认的方法名和类同名。比如 /fruite 等价于 /fruite/fruite

所以我们可以用统一的方式处理路径,通过路径找到相应的类和方法做处理。

GET

读取资源。

DELETE

删除资源,具有幂等性。无论删除多少次,产生的影响都是一样的。本来这块应该是 nginx 处理的,但既然是服务端处理,相关的状态码应该和规范一致。

如果 DELETE method 已经成功处理,服务器应返回如下状态码

默认用 id 做为标识资源唯一性的 key

如果一个资源可以用一个key 找到,这个 key的名字应该是 id。作了这个约定后,可以大大降低沟通成本。 如果一次处理多个 id,id 可以重复。

比如

/fruite/apple?id=1&id=2
复制代码

用 v 表示 版本

我们规定:接口的版本号用参数 v 表示。版本号采用三位表示法。

  1. 第一位:大版本,颠覆性的变化
  2. 第二位:小版本,功能变化
  3. 第三位: 修复版本。用来 fix bug 等小调整。

比如

/fruite/apple?v=1.0.0
/fruite/apple?v=2.1.1
复制代码

默认为最新版本,可以省略 v  不写。

最小版本号为 0.1.0

PUT

用来创建替换资源。具有幂等性。

  • 201 (Created)]  创建成功。
  • 200 (OK)) 替换成功。规范说,返回 204 也可以,我们规定统一返回 200。

POST

如果不适合用前面三种动作,就是 POST。发送的内容可以用三种格式

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

签权

对于危险的动作是应该有限制的,只有授权的用户才可以操作。我们规定签权信息放 header 里。可以放 cookie 或 自定义的头 token 里面。如果是放 cookie里面,key值必须为 token。

为什么还需要 cookie ,统一用 header 不好吗?

  1. 浏览器中用 cookie会更加方便。发请求的时候自动带上。
  2. 在浏览器可以设置 cookie 为 HttpOnly,让 js 无法读取,可以用Secure采用安全通道, 更加安全。

所以在客户端为浏览器的时候还是用 cookie 为好。

案例

我们经常遇到这样的场景,增删改查。如果现在要设计一个 todo list 的 增删改查 的 api ,如何设计呢?

如果不按规范设计,可能得需要 8 个 api。比如 /createItem,/modifyItem...

用规范来设计只需要一个api 就够了。

描述 method path 参数
创建 item POST /item
修改 item PUT /item id
查看所有 item GET /item
查看某个 item GET /item id
删除所有 item DELETE /item
删除 item DELETE /item id
创建月总结 item PUT /item month

如果是删除多个 id 可以这样写 id=1&id=2&id=6

创建 item 用 POST 是因为多次执行会创建多个。

用 PUT 要求多次执行产生的影响一样。月总结每个月只有一个,多次执行也只有一个结果,所以用 PUT。

通过 method,和几个参数的配合,一个接口就完成同一个资源所有操作。这样清晰,也容易沟通,开发效率会大大提高。只要知道资源的名字,就知道如何处理资源。

又比如有一个水果店的项目,有一些苹果,定义苹果的 path /fruite/apple,只需要很少的沟通,前端和服务端立即就知道接口如何写。因为我们规定 id 作为唯一性的 key,用 POST、PUT、DELETE、GET 作为动作,只要明确辅助参数,很容易就能唯一确定接口的写法。

对于创建和删除这样的危险动作肯定是需要权限的。我们前面规定把签权信息放在 header 里。由对应的类和方法做实际的权限验证。

参考

目录
相关文章
|
JSON 负载均衡 前端开发
一文带你详细了解Open API设计规范
一文带你详细了解Open API设计规范
3270 1
|
存储 缓存 安全
API接口设计规范
这个是目前第三方数据接口交互过程中常用的一些参数与使用示例,希望对大家有点帮助。 当然如果为了保证更加的安全,可以加上RSA,RSA2,AES等等加密方式,保证了数据的更加的安全,但是唯一的缺点是加密与解密比较耗费CPU的资源.
|
5月前
|
SQL API Python
Python DB API下规范下cursor对象常用接口
Python DB API下规范下cursor对象常用接口。
82 4
|
3月前
|
安全 前端开发 API
ThinkPHP5 API模块开发规范与示例
【7月更文挑战第6天】本技术文档旨在指导开发者如何完全遵循ThinkPHP5框架的开发规范来构建RESTful API模块。ThinkPHP5(简称TP5)是一款基于PHP的轻量级MVC框架,其简洁、高效的特点非常适合快速开发Web应用及API接口。以下是创建API模块的基本步骤、最佳实践以及代码示例。
156 0
|
4月前
|
存储 Java API
JavaSE——常用API进阶二(2/8)-BigDecimal(BigDecimal的常见构造器、常用方法,用法示例,使用规范)
JavaSE——常用API进阶二(2/8)-BigDecimal(BigDecimal的常见构造器、常用方法,用法示例,使用规范)
40 1
|
5月前
|
JSON Java API
Springboot项目中如何设计一个规范的统一的Restful API 响应框架?
Springboot项目中如何设计一个规范的统一的Restful API 响应框架?
56 1
|
缓存 API 数据格式
要调用API接口获取商品数据,首先需要了解该API的文档和规范
要调用API接口获取商品数据,首先需要了解该API的文档和规范。大多数API都需要使用API密钥进行身份验证,因此您需要先注册API提供商,并从他们那里获取API密钥
|
5月前
|
移动开发 小程序 JavaScript
【uniapp 小程序开发页面篇】代码编写规范 | 页面编写规范 | 小程序API
【uniapp 小程序开发页面篇】代码编写规范 | 页面编写规范 | 小程序API
274 0
|
10月前
|
安全 API 数据安全/隐私保护
API 接口设计规范
API 接口设计规范
404 0
|
API
钉钉的API规范
钉钉的API规范
235 2