心情随笔
如何设计出优秀的API实践
00 分钟
2021-7-2
2023-10-7
type
status
date
slug
summary
tags
category
icon
password
在设计一个API时,首先需要清楚将怎么样的数据经由API公开出去,开发出一套数据访问机制,它能够直接操作服务所用的数据库及其数据表的数据。确定好功能模块之后,可以遵循以下几个原则来进行考虑:

一、URI的基本设计

一个重要的设计原则就是:提供的功能要一目了然且容易理解记忆。为了细分,可以分为以下几条规则:

1.1 短小便于输入


1.2 容易读懂

避免使用过于精简的单词,不用中文拼音,注意单词复数的使用。

1.3 不能大小写混用

大小写混用也会造成API难以理解,容易让人搞错,所以一般都建议全部使用小写。对于URI大小写不统一的问题,处理方式可以有很多种:
  • 无论访问哪一个URI都返回相同结果
  • 将大写字母的URI重定向到只有小写字母的URI处理(可在Nginx转发配置)
  • 将有大写字母的URI视为错误,返回NOT FOUND

1.4 方便修改


1.5 规则统一

这里是指URI所用的单词和URI的结构要统一,比如:

1.6 查询参数与路径

从设计的角度来看,凡是可以附加在查询参数里的信息也都可以附加在URI的路径里。那在设计URI的时候,怎么选择把客户指定的参数放在查询参数还是路径里面?一般通过两个方面来思考:
  • 是否表示资源唯一的信息
    • 这主要基于【URI表示资源】的基本思想,比如用户ID,可以通过用户ID去获取用户的信息,并且该信息是唯一的,所以将用户ID放在路径上会更加合适,另一方面,很多API将“token”等信息用查询参数来指定。这是因为“token”用于用户认证,和资源无关,所以用查询参数更加合理。

  • 是否可以省略
    • 如果一些参数可以省略,比如说offset、limit等,省略了也不会出错,所以放在查询参数更为合适。

二、HTTP方法

正确使用HTTP方法,不仅可以减少URI数量,而且更加符合HTTP语义,比如

对于这样的API:
  • 使用GET方法,表示获取所有订单
  • 使用POST方法,表示新增一个订单
URI和HTTP方法可以理解为操作对象和操作方法之间的关系,如果把URI当作API的操作对象(资源),HTTP方法就表示对资源进行怎么样的操作。
HTTP常用的方法主要有:
方法
说明
GET
获取资源
POST
新增资源
PUT
更新已有资源
DELETE
删除资源
PATCH
更新部分资源
HEAD
获取资源的元信息
CONNECT
建立特殊的链接通道
OPTIONS
列出可对资源实行的方法
TRACE
追踪请求-响应的传输路径

2.1 GET

GET,表示【获取信息】,一般用于获取URI指定的资源。GET具有幂等的特性,所谓幂等(Idempotent)也就是即使反复获取,也不会对访问的数据产生副作用。
另外可以对GET请求的数据做缓存。这个缓存可以是浏览器本身(避免发出HTTP请求),也可以是Nginx或者服务器端(返回304,减少带宽消耗),甚至404页面也可以被缓存。

2.2 POST

POST方法的初衷是【发送附属于指定URI的新建资源信息】,而不是更新资源信息。资源的更新和删除操作有其他HTTP方法完成。
POST方法是存在副作用的,是不幂等的。这也意味着不能随意多次执行,因此也不能被缓存。有不少公司会使用POST代替GET,理由通常也是POST比GET安全。确实是安全一点点,但也只是一点而已。因为HTTP是明文传输的,每个HTTP请求和返回的每一个字节都会在网络上被人瞧的一清二楚,所以这点安全不足以放弃 GET方法,安全问题使用HTTPS才是正道。

2.3 PUT

PUT和POST方法相类似,都可用于对服务器端的信息进行更新,但二者URI的指定方法有所不同。POST方法发送的数据“附属”于指定的URI,附属表示从属于URI之下。比如说在文件系统中,把文件放入目录后,文件就成了目录的附属部分。所以,对文件目录或分类等表示数据集合的URI进行POST操作后,就会产生从属于原有集合的新数据。
在另一方面,PUT方法则指定需要更新资源的URI本身,并对其内容进行覆盖。如果URI资源已经存在,PUT操作就意味着对资源进行更新。虽然HTTP协议也定义了当指定的资源不存在时,可以通过PUT操作发送数据,生成新的资源,但Web API一般只用PUT方法来更新数据,而一般会使用POST来生成新的资源。

2.4 PATCH

PATCH和PUT方法相同,都用于更新指定的资源。但PATCH方法并不是更新资源的全部信息,而是只更新资源的一部分。PUT方法会使用发送的数据替换原有的资源信息,而PATCH方法只会更新原有资源中的部分信息。
PATCH方法发布的路程可谓是一波三折。它最早是在RPC2068中被定义,但由于没什么人使用,后来在RFC2616中被删掉了,但是在2010年3月发布的RFC6789中被再次提起并定义。
 

2.5 HEAD

HEAD方法与GET方法类似,也是请求从服务器获取资源,服务器处理的机制也类似,但服务器一般不会返回请求的实体数据,只会传回响应头,也就是资源的【元信息】。
HEAD方法可以看作是GET的一个“简化版”。因为它的响应头与GET完全相同,所以可以用在很多并不真正需要资源的场景中,避免传输body数据带来的带宽消耗。
比如说,想要检查一个文件是否存在,只要发HEAD请求即可,没有必要用GET把整个文件都取下来。