对外公开 Web API 时,必须首先思考将怎样的信息或数据经由怎样的 API 对外公开。接下来就让我们来考虑一下如何决定对外公开的功能和端点,以及 Web API 的端点该如何设计。
从本章开始,我们将讲解 API 具体的设计规则及方法。
### API 端点的设计思想
在 Web API 的语境里,端点是指用于访问 API的 URI。一般而言,因为 API 将各种不同的功能进行了封装,所以会拥有多个不同的端点。实现不同的功能就需要分别赋予其不同的端点,即访问这些功能的 API 所需的 URI。
比如,在设计获取用户信息的 API 时,可以分配如下 URI,API 用户可以通过访问端点使用 API 提供的功能。
~~~
https://api.example.com/v1/users/me
~~~
#### 端点的基本设计
要探讨什么是优秀的 URI 设计,有一个非常重要的原则,如下所示。
~~~
容易记忆,URI 包含的功能一目了然。
~~~
API 是供计算机程序机械地访问的,但是还需要人眼看上去也易于理解,设计出便于开发人员理解的端点可以有效降低开发人员搞错 API 端点或错误使用 API的概率。这不仅可以提高开发人员的生产效率,还有助于提升 API 的口碑。
设计优美的 URI 的方法,我们可以总结出如下几个普适又重要的原则。
短小便于输入的 URI
人可以读懂的 URI
没有大小写混用的 URI
修改方便的 URI
不会暴露服务器端架构的 URI
规则统一的 URI
接下来让我们结合 API 的设计思想逐一了解以上这些原则。
1. 短小便于输入的 URI
在表示的信息量相同的情况下,使用短小、简单的表述方式更易于理解和记忆,并能减少输入时的错误。
~~~
http://api.example.com/service/api/search
~~~
该 URI 和下面这个简短的 URI 所包含的信息基本没有什么差别。
~~~
http://api.example.com/search
~~~
2. 人可以读懂的 URI
为了避免设计出这样难以理解的 URI,首先就要做到不轻易使用缩写形式,虽然有人认为这些缩写形式对于母语是英语的人而言非常常见,但即使这样,也不建议过度使用省略和缩写形式。因为使用 API 的开发人员的母语未必是英语。使用全世界通用的英语来描述可以使 API 更易于理解。
另外,即使看起来是同一个缩写形式,也存在细微的差别,比如表示国家名称的“jp”“jpn”等。使用标准化的“代码”体系来标识,比使用其他符号会更易于理解。
要设计容易理解的 URI,就要使用 API 里常用的英语单词。
对于 API 里常用的单词,人们往往已经形成共识,一般会默认“该单词是用来表示某某功能或某某信息的”,因此,使用 API 里常用的单词,有助于让人仅通过 URI就能理解它的意思。
要设计容易理解的 URI,第 3 个要点就是要尽可能地避免拼写错误。对于母语非英语的人而言,这一点尤其应引起注意。
易于理解的 URI 还可以减轻用户编写访问 API 的代码时的负担。因为如果从URI 就能知道该 API 的用途,那么开发人员在阅读访问该 API 的代码时,就可以不用每次都去翻阅 API 的相关文档,从而大幅提高了工作效率。另外,这也会减少开发人员因 URI 难以理解而访问了错误的 URI 进而访问了错误的 API 的情形。
3. 没有大小写混用的 URI
不要使用如下例所示的大小写混用的 URI,一般建议全部使用小写字母的形式。
~~~
http://api.example.com/Users/12345
http://example.com/API/getUserName
~~~
大小写字母混用会造成 API 难以理解,容易让人搞错。因此需要统一为全部大写或全部小写,一般标准的做法是全部使用小写。
另外,统一使用小写字母和忽略字母大小写从严格意义上来说仍有区别。忽略字母大小写时,也是就说,在访问大小写字母混用的 URI 时,是不是应该将其统一视为小写字母,进行相同的处理并返回相同的结果呢?
~~~
http://api.example.com/USERS/12345
http://api.example.com/users/12345
~~~
对于上面的 URI,可以有多种处理方式:
1. 无论访问哪个 URI 都一并返回相同的结果;
2. 将混有大写字母的 URI 重定向到只有小写字母的 URI 进行处理;
3. 将混有大写字母的 URI 视为错误的 URI 并简单地返回 Not Found;
4. 不识别混有大写字母的URI,等等。
普通的 Web 页面的情况下,如果采用“无论访问哪个 URI 都一并返回相同的结果”这种处理方式,Google 等搜索引擎便会认为有多个页面返回了相同的结果,从而导致网页排名(PageRank)下降。因此,对于普通的 Web 页面而言,采用返回 301 代码并将页面进行重定向的方法最为合适。因为 API 不会涉及搜索引擎的可搜索性等问题,所以页面排名下降的问题并不存在。
HTTP 协议里原本就规定了 URI“除了模式(schema)和主机名以外,其他信息都需要区分字母的大小写”(RFC 7230)。因此,只要端点描述使用了小写字母,混入大写字母时就理所当然地会出错,关于这一点可以说不会有任何疑问。
4. 修改方便的 URI
“修改方便”即英语中所说的“Hackable”。“修改方便的 URI”指的是能将某个URI 非常容易地修改为另一个 URI。假设我们需要获取某种商品(item,根据 API类型的不同而发生变化),该 API 的端点如下所示。
~~~
http://api.example.com/v1/items/12346
~~~
从以上 URI 能直观地看出该商品 ID 为 123456,并且可以猜测只要修改这一ID,就能访问到其他商品的信息。
6. 规则统一的 URI
这里提到的规则是指 URI 所用的词汇和 URI 的结构等。对外提供 Web API 时,仅用一个或一种规则来描述端点的情况很少见,多数情况下都会公开多个 API 端点。
在本章开篇提及的 SNS 在线服务的范例里就提供了获取好友信息、发送消息等多种功能的 API。如果这些 API 分别采取相同的规则进行设计,结果会如何呢?
如果使用如下所示的规则统一的 URI,便会很容易理解。
❖ 获取好友信息
~~~
http://api.example.com/friends/100
~~~
❖ 发送消息
~~~
http://api.example.com/friends/100/message
~~~
在以上示例里,获取好友信息的 API 里使用了 friends 这样的复数形式,ID信息通过查询参数进行传递。