跳转至

Web API的设计与开发

本文是《Web API的设计与开发》的读书笔记,仅供参考

20240623165655-40b65-image.png

Checklist

在进行 WebAPI 设计时,下面的检查项需要重点关注。

URI 设计

  • URI 是否短小且容易输入
  • URI 是否能让人一眼看懂
  • URI 是否只有小写字母组成
  • URI 是否容易修改
  • URI 是否反映了服务器端的架构
  • URI 规则是否统一
  • URI 里用到的单词所表示的意思是否和大部分 API 相同
  • URI 里用到的名词是否采用了复数形式
  • URI 里有没有空格符及需要编码的字符
  • URI 里的单词和单词之间有没有使用连接符
  • 有没有在 URI 里嵌入主版本编号,并且能够让人一目了然

HTTP 方法与状态码

  • 有没有使用合适的 HTTP 方法
  • 出错时有没有返回 HTML 数据
  • 有没有返回合适的状态码
  • 服务器端在维护时有没有返回 503 状态码

响应数据设计

  • 响应数据格式有没有使用 JSON 作为默认格式
  • 响应数据的内容能不能从客户端指定
  • 响应数据中是否存在不必要的封装
  • 响应数据的结构有没有尽量做到扁平化
  • 响应数据有没有用对象来描述,而不是用数组
  • 响应数据的名称所选用的单词的意思是否和大部分 API 相同
  • 响应数据的名称有没有用尽可能少的单词来描述
  • 响应数据的名称由多个单词连接而成时,连接方法在整个 API 里是否一致
  • 响应数据的名称有没有使用奇怪的缩写形式
  • 响应数据的名称的单复数形式是否和数据内容相一致
  • 出错时响应数据里是否包含有助于客户端剖析原因的信息
  • 有没有返回合适的媒体类型

安全性

  • 登录有没有使用 OAuth 2.0
  • 有没有使用 HTTPS 来提供 API
  • 有没有认真执行 JSON 转义
  • 能不能识别 x-Requested-With 首部,让浏览器无法通过 SCRIPT 元素读取 JSON 数据
  • 通过浏览器访问的 API 有没有使用 XSRF token
  • API 在接受数据时有没有仔细检查非法的参数(负数等)
  • 有没有做到即使请求重复发送,数据也不会多次更新
  • 有没有在响应消息里添加各种增强安全性的首部
  • 有没有实施访问限制

缓存与性能

  • 有没有返回 Cache-Control, ETag, Last-Modified, Vary 等首部以便客户端用合适的缓存策略
  • 不想缓存的数据有没有添加 Cache-Control: no-cache 首部信息

版本管理

  • 有没有对 API 进行版本管理
  • API 版本的命名有没有遵循语义化版本控制规范
  • 有没有考虑 API 终止提供时的相关事项
  • 有没有在文档里明确注明 API 的最迟提供期限

其他设计考量

  • 分页的设计是否恰当
  • 响应数据的名称有没有使用奇怪的缩写形式
  • 必要时能不能支持 CORS
  • 对预想的用例标准限定的次数有没有设置得过少
  • 是否支持通过查询参数来指定数据格式
  • 是否支持不必要的 JSONP

第1章 什么是Web API

设计原则

  • 设计规范明确的内容必须遵守相关规范
  • 没有设计规范的内容必须遵守相关事实标准

两类API

  • LSUD: Large Set of Unknown Developers
  • SSKD: Small Set of Known Developers

第2章 端点的设计与请求的形式

常见HTTP方法的使用场景

  • GET : 获取资源
  • POST : 创建资源
  • DELETE : 删除资源
  • PUT : 更新资源(全部信息)
  • PATCH : 更新资源(部分信息)
  • HEAD : 获取资源(元数据)

常见的端点形式

  • 蛇形法(Snake Case): /api/v1/users/profile_image
  • 脊柱法(Spinal Case): /api/v1/users/profile-image
  • 驼峰法(Camel Case): /api/v1/users/ProfileImage

注意:如没有特殊要求,使用蛇形法

第3章 响应数据的设计

为什么JSON比XML应用更广泛

JSON可以使用更简单的方式来这边雨相同的数据,占用空间更小,并且还能同web默认的客户端语言JavaScript更好地兼容

日期格式

优先使用下面的数据格式

  • RFC 3339: 2006-01-02T15:04:05+08:00
  • Unix时间戳: 1136185445

注意: RFC 3339是ISO 8601的子集

第4章 最大程度地利用HTTP协议规范

状态码首位的大概含义

状态码 含义
1字头 消息
2字头 成功
3字头 重定向
4字头 客户端原因引起的错误
5字头 服务器端原因引起的错误

主要的HTTP状态码

状态码 名称 说明
200 OK 请求成功(GET/PUT/PATCH OK)
201 Created 请求成功,新的资源已创建(POST OK)
202 Accepted 请求成功
204 No Content 没有内容(DELETE OK)
300 Multiple Choices 存在多个资源
301 Moved Permanently 资源被永久转移
302 Found 请求的资源被暂时转移
303 See Other 引用他处
304 Not Modified 自上一次访问后没有发生更新
307 Temporary Redirect 请求的资源被暂时转移
400 Bad Request 请求不正确
401 Unauthorized 需要认证(我不知道你是谁)
403 Forbidden 禁止访问(我知道你是谁,但你没有执行操作的权限)
404 Not Found 没有找到指定的资源
405 Method Not Allowed 无法使用指定的方法
406 Not Acceptable 同Accept相关联的请求部件含有无法处理的内容
408 Request Timeout 请求在规定时间内没有处理结束
409 Conflict 资源存在冲突
410 Gone 指定的资源已不存在
413 Request Entity Too Large 请求消息体太大
414 Request-URI Too Long 请求的URI太长
415 Unsupported Media Type 不支持所指定的媒体类型
429 Too Many Requests 请求次数过多(限流)
500 Internal Server Error 服务器遇到错误
503 Service Unavailable 服务器暂时停止运行

第5章 开发方便更改设计的Web API

如何管理版本号

最为常用的还是在URI的路径中嵌入版本信息,并遵循语义化版本控制的规范,使用主版本编号

访问废弃版本号的响应

410,表示当前API已经停止对外公开,请使用新版本

第6章 开发牢固的Web API

问题分类

非法获取服务器端和客户端之间的信息

  • 利用HTTPS对HTTP通信实施加密

利用服务器端的漏洞非法获取和篡改信息

  • JSON劫持

预设通过浏览器访问的API中问题

  • XSS: Cross Site Scripting, 跨站脚本
  • XSRF: Cross Site Request Forgery, 跨站请求伪造

安全相关的HTTP头部

  • X-Content-Type-Options: nosniff, 防止浏览器将JSON数据按照非JSON类型解释
  • X-XSS-Protection: 1; mode=block, 浏览器可以有效地检测个防御XSS攻击
  • X-Frame-Options: DENY, 防止浏览器将页面嵌入到框架中
  • Content-Security-Policy: default-src 'self', 指定了默认的资源加载策略,即只允许从与当前页面相同的源('self')加载资源
  • Strict-Transport-Security: max-age=31536000; includeSubDomains, 强制浏览器通过 HTTPS 访问网站,从而提高网站的安全性,防止中间人攻击和协议降级攻击

限速相关的HTTP头部

  • X-RateLimit-Limit: 1000, 在一个单位时间内允许的最大请求数
  • X-RateLimit-Remaining: 999, 在当前时间窗口内剩余的请求次数
  • X-RateLimit-Reset: 100, 当前时间窗口结束并重置为新窗口的 Unix 时间戳

参考