引言
这是观看书籍<Web api的设计与开发>这本书时,作的笔记
1 url命名的问题
- 不要大小写混用
- 不要一会单数、一会复数,比如不提倡:
http://api.example.com/friends?id=100 获取好友信息
http://api.example.com/friend/100/message 给好友发送消息
提倡:
http://api.example.com/friends/100
http://api.example.com/friends/100/message
-
到底是用复数还是用单数? 有时用单数来表示特定的一个资源也没有问题;况且有的单复数同形,单数变复数的规则也很多,母语非英文的就容易搞错;动词update本身没有复数,但是用来表示更新的次数就是可以数性质了。
-
不使用空格以及需要编码的字符
-
多个单词要尽量避免,连接提倡使用连接符"-“的脊分法,比如:/v1/people-search,而不是蛇形法people_search或点分法people.search,因为google搜索忽略”“作为单词的延续,另外”“与 下划线在其它情况下的应用有视觉上的重复冲突,URI里的主机名(域名)允许连字符而不允许下划线,点字符具有特殊含义,因此提倡连字符连接单词
2 使用什么PATH参数
比如DELETE http://api.example.com/v1/users/:id/friends/:id 删除好友,这里用的是好友ID,而不是好友关系记录的ID, 有两个原因:
-
形成了"自己的用户ID” + “好友的用户ID"来表示特定资源(两人之间的好友关系)
-
理解和使用相对方便
-
即便存在关系ID,也没必要让用户意识到,需要强调的是:
系统内部的架构信息没有必要在API中反映出来
3 神奇的定语
restful接口提倡用名词来表示资源,那获取好友(可能有几个)的动态列表,如何设定URL?
GET http://api.example.com/v1/users/:id/friends/updates,就是这个updates表示所有好友的更新
4 尽量减少api数量
为了完成一项任务,需要多次访问api,这样的api设计叫作Chatty API
,会加大网络流量的消耗,增加客户端的处理工序,给用户留下难用
的印象。因此尽可能多地返回信息,
但是如果返回了大量的客户端用不上的信息,却触犯另一个原则,尽可能发送较少数据量。用例复杂多样的话,确定返回合适的结果也是非常困难的,服务范围较大的API,
常用的应对办法就是使用户能够选择要获取的项目,比如在API调用时通过查询参数来指定,比如:/v1/users/123456?fields=name,age
,也可以用设定响应群组,每一个组对应一些
返回数据项。
5 是否要封装
比如按照header/response来封装返回的数据,这里header放一些http状态字,就没有充分利用HTTP协议的机制,但是JSONP的时候,使用封装机制会更加便利,因为JSONP的情况下, 浏览器在读取数据时无法访问状态码及响应消息体。另外,返回的数据尽量扁平化。
6 日期的格式
通常有RFC 822/RFC 850/ANSIC的asctime()格式/RFC 3339/UNIX时间戳(epoch秒),提供使用RFC3339标准格式,比如:2015-10-12T11:30:22+09:00
,
但是HTTP header中的时间仅支持前面三种格式,而且如果一开始就可以预测用户的状态,比如调用API的客户端仅仅是公司内部的智能手机应用,可以用简洁的unix时间戳也可以。
RFC3339有几个特点:
- 年、月、日用数字来表示,符合我们的习惯;
- 北京时区
+08:00
,不过考虑到互联网,在HTTP首部中通常会采用UTC来表示HTTP时间 ,因此推荐使用时区+00:00
,可以通过Z
来标记:2015-11-02T13:00:12Z
,如果用2015-10-12T11:30:22-00:00
表示时区不明。
7 错误信息的返回
twitter的做法是将错误以序列的形式返回,非常适合多个错误同时发生时的描述:
{
"error":[
{
"message": "Bad Authentication data",
"code": 215
}
]
- code最好是分组,比如1字开头的表示哪一类,2字开头表示用户信息错误等
- 还可以考虑将信息区分为面向用户的,和面向开发者的:developerMessage/userMessage
- 可以考虑接口文档提示出来:
"info" : "https://docs.xx/api/v1/authentication"