当我们开始从事API开发的时候,设计问题便出现了. 一个强而有力的API设计方法是API成功的关键要素. 设计糟糕的API会导致API滥用问题,或者更糟:API根本没人使用 (指Web开发者).
建立和提供一个艺术品级别的API需要考虑一下几点:
- 使用如部分资料中所描述的RESTful API原则 (Roy Fielding[1], Martin Fowler[2], HTTP 规范等).
- 参考Web巨头的做法,例如Google, Microsoft, Facebook, PayPal 和其他大公司.
关于如何设计一个REST 风格的API这个问题,目前没有通用答案. 而REST 风格的最佳实践这个问题仍然处于辩论和巩固中,这就是为什么这项工作很迷人的原因.
以下是 设计一个 RESTful 风格的 API[3] 的5项基本原则:
- URI资源
- HTTP 方法
- HTTP 头
我们依次来解释一下.
1. URI资源
使用名称和动作(获取)
要描述你所拥有的资源, 使用具体名词代替行为动词(指API命名方式).
许多年以来,电脑科学家使用行为动词来暴露以RPC方式构建的服务接口, 例如: getUser(1234)createUser(user)deleteAddress(1234)
相比而言, RESTful 风格是这样做的:GET /users/1234POST /users (在请求体重使用JSON描述一个用户对象)DELETE /addresses/1234
URI 命名
涉及到给项目中的资源明明时,有三种主要的命名约定方式: 驼峰命名法(CamelCase), 蛇形命名法(snake_case), 和 脊柱形命名法(spinal-case). 这些命名法则类似于我们使用的自然语言,他们只是一种命名资源的方式,使用他们时要避免引入空格,撇号等特殊字符. 这些法则在编程语言中很通用,因为他们只使用一组有限的特性为变量命名.
驼峰命名法(CamelCase)
驼峰命名法在Java语言中很流行 !?. 它将每个单词的首字母大写,例如 camelCase, currentUser,等. 抛弃对这种命名法的可读性的争议,它主要的缺点是在大小写不敏感的上下文中这种方式命名的不同变量来讲是无效的(有些语言是忽略大小写的,例如T-SQL的变量声明).
蛇形命名法(snake_case)
蛇形命名法已经被C程序员们广泛使用很多年了, 并且最近也在Ruby语言中流行开来. 这种命名法使用下划线"_"分割单词, 这样可以使编译器或解释器更容易的理解他们,而且对代码阅读这也很友好. 然而, 它的热度正在下降,原因在于这种命名法在C程序中的过度滥用或者使用他们创造了太多短名字(指不容易理解吧). 不像驼峰命名法, 蛇形命名法只有在极少数情况下才不使用(指被滥用了). 例如: snakecase, currentuser, 等等.
脊柱命名法(spinal-case)
脊柱命名法是使用连字符 "-" 分割单词的一种蛇形命名法的变体. 它的优点与缺点跟蛇形命名法非常相似, 只是有项例外是有的语言不允许使用连字符用来定义符号名称 (例如声明变量,class起名或函数命名时). 你可能会发现它参考了lisp命名的写法,因为lisp方言就是这么做的. 这种命名法也是Unix和Linux系统中传统的文件夹命名方式. 例如: spinal-case, current-user, 等等.
根据文档 RFC3986 规定, URL是大小写敏感的 (除了主机头等信息).
实际情况中,大小写敏感问题可能会对在Windows环境托管的API导致出现问题.
所以建议使用脊柱命名法(spinal-case) ( RFC3986 文档中突出强调了这一点), 这种命名法也被 Google, PayPal 和其他大公司使用.

2. HTTP 方法
如前所述, 建立一个REST风格的API 的主要关键目标之一是使用HTTP协议作为应用程序的协议,从而避免制作出“土造”的REST风格API(好难翻). 因此, 我们应当系统的使用HTTP谓词来描述对资源所要执行的操作,并且让开发人员可以方便的处理重复的CRUD操作.
经常会看到以下方法:
GET 方法被用作从给定的服务器中通过给定URI检索信息。使用 GET 来请求应该仅对数据进行检索,而不对数据产生其他影响。
和 GET 一样,但是只传输状态行(status line)和头部分(header section)。
POST 请求用于发送数据至服务器,举个栗子,用户信息,文件上传等。通过 HTML 表单发送请求。
用上传的内容替换目标资源当前所有的资源表示(数据)。
DELETE
删除由 URI 给定的目标资源当前所有的资源表示(数据)。
OPTIONS
描述目标资源的通信参数.
3. HTTP头
HTTP头的字段提供了有关请求或应答必要的信息,或者提供了有关消息体重发送的对象的信息.
HTTP消息头有4种类型:
一般头: 这些头的字段对请求和响应消息有通用性.
客户端请求头: 这些头的字段只能应用于请求消息.
服务器响应头: 这些头的字段只能应用于响应消息.
实体头:这些头的字段定义了有关实体正文的元信息,如果这儿没有正文,则定义有关请求确认的资源的元信息

4. 查询参数
在你API设计的早期阶段预估资源的分页是有必要的.但要精准地预计返回数据的总数是非常难的.因此,我们建议当调用客户端没有提供每页条数时,用默认的值例如[0-25]范围的某个对你的资源进行分页.
过滤条件用于通过制定某些属性和它们期望的值限制查询资源的总数.可以同时在多个属性上过滤一个集合,也可以在一个过滤属性上指定多个值
排序是指在集合资源上的查询结果进行排序.排序参数需要包含进行排序的字段的名字,并以逗号隔开.
搜索是一个集合的子资源.因此,搜索的结果有与资源和集合本身不同的格式.这使得我们可以添加建议,修正和与该搜索相关的其他信息.搜索提供参数的方式与过滤相同----都是通过查询参数,但是搜索参数不需要精确的值,并且搜索参数的语言允许近似匹配.
5. 状态码
状态码对于RESTful API非常重要, 尤其当你在 模拟测试 RESTful API[4] 时.
最常用的状态码如下:
200 – OK .
201 – CREATED: 新资源已被建立.
204 – NO CONTENT: 资源删除成功 (无响应体).
304 – NOT MODIFIED: 返回数据是缓存中的内容 (数据没有改变).
400 – BAD REQUEST: 请求无效或者服务端无法响应请求. 确切的错误应该在有效载荷中(具体传输的数据包?)中找到. 例如这样的错误 „The JSON is not valid“.
401 – UNAUTHORIZED: 请求需要用户验证.
403 – FORBIDDEN: 拒绝访问.
404 – NOT FOUND: 找不到文件.
500 – INTERNAL SERVER ERROR: API 开发者应当避免这种错误. 如果这种错误在全局异常中被捕获, stack trace会记录下这个错误并且不会返回响应内容.
REST 不是个新事物. REST 是大型应用服务器所用各式各样获取数据方式的一种回归, 通过它来强调早期的Internet,URI标准和HTTP标准(返璞归真,阿弥陀佛).
资源建模(指REST风格API设计)需要基于业务需求做仔细考虑, 技术开发注意事项(纯粹的架构设计,可维护性等)和成本效益分析等前面已经讨论过的各种各样的方法,通过做这些以便创造出更加易于用户体验的API.
过去有一篇文章叫《设计并开发 RESTful API[5]》. 这些内容希望有助于你创建纯净,易用、易理解的API.