前言
在设计API的过程,首先我们需要明确的就是 URL 规范。因为如果 URL 不规范,那就会导致让人很烦恼的 URL 路径出现。
例如:
# 1.莫名奇妙出现了一个大写,这个还算好的。但是有些系统大小写敏感,上面这两个就会是认为两个不同的路径地址
/api/v1.0/crash/systemMem
/api/v1.0/crash/systemmem
# 2.冗长的url路径,看起来都痛苦
/servlet/ArticleNews/PEstory/TGAM/20020909/RVCRR/Business/business/business_temp/2/2/5/
# 3.不常见的标点符号:下面用上了 下划线_ 还有 加号+ ,这种路径读起来很难记忆,比较酸爽。
/pub/docs/moon_3+manual
# 4.在纸介质上显示很困难
一些字符在纸上打印出来不容易辨认,例如:
- ~(数字键1旁边那个键)在不同的字体下面显示不同,有时候在一行的顶部,有时候在底部。
- l(字母L的小写版本)和“1”(数字一)几乎无法分辨——在纸介质上的时候,同样的还有“O”和“0”。
- ` 太微小,以致于人们在某些情况下看不到它。
/api/v1.0/hel~ll1o0O # 这样的URL看起来太痛苦了。
可以从上面的示例来看,我们就感觉到,我们需要一个好的规范去约束 URL 的设计。
设计URL应该遵循的原则
- 简单,好记的域名
- 简短(short)的URL
- 容易录入的URL
- URL能反应站点的结构
- URL是可以被用户猜测和hack的(也鼓励用户如此)
- 永久链接,Cool URL don't change
一定要短
为了URL能被方便的录入,写下,拼写和记忆,URL要尽可能的短.
根据w3c提供的参考数据,一个URL的长度最好不要超过80个字节(这并非一个技术限制,经验和统计提供的数据),包括schema和host,port等。
大小写策略
URL的大小写策略要适当,要么全部小写,要么首字母大写,应避免混乱的大小写组合。
在Unix世界,文件路径队大小写是敏感的。
而在Windows世界,则不对大小写敏感。
所以,http://www.example.com/FOO 和 http://www.example.com/foo 是两个不同的URI(尽管他们在Windows平台有相同的含义)
URL 映射
管理员可以重新组织服务器上的文件系统结构,而无需改动URL,这就需要URL和真实的服务器文件系统结构之间有一个映射机制,而不是生硬的对应。
这种映射机制可以通过如下技术手段实现:
Aliases,别名,Apache上的目录别名,IIS上的虚拟目录
Symbolic links,符号链接,Unix世界的符号链接
Table or database of mappings,数据库映射,URI和文件系统结构的对应关系存储在数据库中
标准的重定向
管理员可以简单的通过修改HTTP状态代码来实现服务器文件系统结构变更之后的URL兼容,可以利用的HTTP Status Code有:
301 Moved Permanently ([RFC2616] section 10.3.2)
302 Found (undefined redirect scheme, [RFC2616] Section 10.3.3)
Temporary Redirect ([RFC2616] Section 10.3.8)
URL 规范
根据上面的一些准寻的原则,我们可以设定一些项目开发中的 URL 设计规范,如下:
1. 不用大写 (强制)
2. 用中杠-不用下杠_(强制)
3. 参数列表要encode,编码使用utf-8(强制)
4. URI中的名词表示资源集合,使用复数形式。(建议)
5. 增加版本号(建议)
URL中统一使用小写字母
根据RFC3986
定义,URI是对大小写敏感的,所以为了避免歧义,我们尽量用小写字符。
URL中尽量使用 连字符 -
代替 下划线 _ 的使用
连字符"-"一般用来分割URL中出现的字符串(单词),来提高URL的可读性,例如:
http://api.example.restapi.org/blogs/mark-masse/entries/this-is-my-first-post
说明:
使用下划线"_"来分割字符串(单词)可能会和链接的样式冲突重叠,而影响阅读性。
但实际上,"-"和"_"对URL中字符串的分割语意上还是有些差异的:"-"分割的字符串(单词)一般各自都具有独立的含义,可参见上面的例子。而"_"一般用于对一个整体含义的字符串做了层级的分割,方便阅读,例如你想在URL中体现一个ip地址的信息:210_110_25_88 .
URL增加版本号
根据项目的更新,原来的URL可能被多个项目所使用,需要兼容原有系统的情况下,支持新业务。
提供给内部系统使用的api,建议使用/api/v1/
开头, 提供给前端APP使用的api,建议使用/web-api/v1/
开头
/api/v1/loan
/web-api/v1/loan
资源集合 vs 单个资源
URL表示资源的两种方式:资源集合、单个资源。
资源集合:
/zoos //所有动物园
/zoos/1/animals //id为1的动物园中的所有动物
单个资源:
/zoos/1 //id为1的动物园
避免层级过深的URL
/
在url
中表达层级,用于按实体关联关系进行对象导航,一般根据id
导航。
过深的导航容易导致url
膨胀,不易维护,如 GET /zoos/1/areas/3/animals/4
尽量使用查询参数代替路径中的实体导航,如 GET /animals?zoo=1&area=3