越是高级的东西越简单,越是真理越明了。一种观点,一种学说,如果不能用简约平易的方式去表达,那它还是不是真理,就值得怀疑。
——易中天
REST系统
一个符合REST设计风格的系统,一般来说,需要满足6大原则:
- C/S 结构
- 无状态
- 可缓存
- 分层系统
- 按需编码
- 统一接口
从实际开发中,有些原则是不言自明的,比如C/S结构,比如http协议,所以客户端开发者需要“盯住”的最重要的三个特征是:
- 无状态
- 统一资源定位
- 可缓存性
无状态
做过开发的小伙伴就纳闷了,我开发的APP(比如:微博APP)有状态啊,比如登录,明显就是一个状态。
这里的无状态是从服务器角度理解的,比如调用个人信息接口,有状态的设计是服务端用IP地址来识别客户端,然后根据保存的登录状态来返回个人信息,这样的服务器多忙啊,成千上万的客户端,一一记住它们的登录状态,还要识别各个客户端;
而无状态的设计就是我们现在常见的:登录调用登录URL,成功后得到token,客户端自己保存这个token,调用个人信息接口时,把这个token作为调用信息一起传入,服务器不用识别每个客户端,只要验证token是有效的,就把对应个人信息返回,这样,无论有多少客户端发起请求,无论请求多少次,服务器只管验证每次传上来的信息是否满足约定的规则即可,无需关心它们原先的状态是什么。
那么逻辑上的状态怎么处理呢?由客户端自己维护状态,如保留token值,判断token是否过期失效等等。
统一资源定位
REST将服务器上的所有信息都抽象为资源,任何信息都是资源:文档、图片、时间相关的服务(如北京的今日天气),也可以是非虚拟的对象,比如一个人,另外以上资源的集合也是一种资源。资源是映射到一个链接上的事物概念,而不是某个时间点的具体事物,理解资源的定义,是理解这种设计的关键。
可缓存
在我看来,可缓存就是无状态+URL的副产品,正是各种信息能被统一表示,且没有前后的状态逻辑,缓存信息才成为可能,我们常见的就是按URL缓存,这是一款互联网APP提升可感知性能的基础。
当然有些信息是不能被缓存的,比如春运火车票的余票数量(12306要是这么设计,程序员真要被拉去祭天了😂)
什么是RESTful API
下面通过分析一个实际的API,来体会下什么是REST风格的API:
优秀RESTful API 赏析
想看特朗普的推特文章列表,就访问如下URL:
http://twitter.com/statuses/user_timeline.xml?id=realdonaldtrump
这串像目录名一样的字符串:
http://
表明将要使用超文本传输协议,这基本上与REST是等价的通信协议;
twitter.com
部分是域名,表明了将要访问位于该名字所映射到的 IP 地址的一个资源;
/statuses
可以将它想象为文件系统内的一个目录,只不过在twitter的服务器上,它可能只是一个方法名或类名,并不是一个物理磁盘上的文件夹;
user_timeline
同理,user_timeline是最后调用函数的实际名称;
.xml
扩展名是指返回的数据格式,而不是操作系统中的文件后缀(尽管逻辑含义类似),在一些可选择的API设计中,改成user_timeline.json
就可以获得json格式的返回信息,这很好的体现了RESTful API 设计带来的灵活性;
?id=realdonaldtrump
?
表示后面是前面函数的参数,id
表明参数名,=
后面紧跟参数值realdonaldtrump
,这里表示特朗普。
看到这里,是不是有一种强烈的感觉,没错!
一个良好的REST风格的接口,看起来就像是 …呃…一个普通的“超链接”!
这里告诉你个小秘密:REST的提出者 Roy Fielding 就是HTTP协议的制定者之一,所以你现在理解了吧,据说老爷子当年发明HTTP,想着这套标准能造互联网上的原子弹,至少也是洲际导弹,结果大家只用它来放烟花,可把老爷子给气的,于是2000年时长篇大论,整出了REST架构。
思考题:
前面提到火车票是不应该被缓存的,那么什么情况下最适合缓存呢,请举例说明?经过深度思考的知识才能准确理解哦,期待你的留言。