RESTful风格
挖坑继续,之前上一次分享,已经是很久以前了。。。最近忙着写一个针对网络运维的分布式采集系统,闲下来的时间也是在思考设计这个玩意儿,所以没打理公众号。今天赶紧补一点,不然怕掉粉。觉得我写得好,欢迎分享,觉得我写的不好,请给我一个改正的机会。
书接上文,我们分享了http协议的一些基础知识。今天我们来讲讲HTTP 接口的“旧”贵RESTFul API,为什么说是旧,因为它的诞生距今已经有20年。而且最近也有挑战者了。
它出自20年前的一篇论文,论文地址我会放到最后,刚开始写的时候我还没看这个论文,我估计我会在写这个文章的时候去稍微看看。。。
所以以下内容,基本是网上的拾人牙慧加我自己的理解。
什么是REST风格
REST有什么特点
RESTf风格API长什么样子
我们说的REST到底是什么东西
工作交流中我们时常讲“我们要RESTful API”,“我们支持REST API”,“你们有REST接口吗”,这个REST是什么鬼?如果你这样问我,我肯定会话到嘴边,又不知道说什么,因为好像知道你问的东西是什么,但是却没有一个明确的定义,无法表述。
今天我们先来说说,什么是REST,它可不是rest休息。
Representational State Transfer (REST)
翻译过来就是表述层的状态转移。。。看不懂?我也是。
简单直白的理解是,网络资源基于http协议,在一种比较有约束的规范下,进行交互,从而使资源发生了变化(增删查改)。
本来我试图通过看论文写好这个文章,后来发现论文实在是很晦涩,从头到尾讲的是一些高屋建瓴的原则,。想想也是,博士论文写几个URL好像不是那么高大上,讲最佳实践和例子这些事情,是工程实现的东西。所以我决定换个思路写写。
- rest是一种风格,约束,指导,帮助我们落地设计比较好的基于HTTP的网络应用间沟通方式。
- 它使用的是简单的机制, REST 使用HTTP的方法来实现对资源的4种CRUD (Create/Read/Update/Delete) 操作,比如查询(read)用get。删除用delete
- 在实际使用中,它是重量级RPC (Remote Procedure Calls) 和Web Services (SOAP, WSDL等)的轻量级替代方案。
- 它没有被落到纸面,遵循大体的风格你也可以称之为restful api
- 还有一点很重要,它是stateless的,没有状态的,没有上下文,本次的交互和上一次的交互下一次的交互没有什么关系,他们是相互独立的
估计还是没讲清楚,没关系,估计也讲不清楚,大家看看一些实践去体会吧,就好比麻将,说不明白,玩两盘你就知道了。
RESTful 风格API鉴赏
名词表示资源位置
# 设备列表的api
api/cmdb/devices
# 端口列表的api
api/cmdb/interfaces
# 版本号为1的api
api/v1/cmdb/interfaces
- 在没有域名的情况下,一般url 或者称endpoint中 会加“api”表明是api
- 中间基本是名词,资源也是用名词,且多是复数。层次比较丰富的api,可以比较有效的组织资源,比如cmdb代表的是一个app或者db,device是这个app或者db中的一个具体的资源或者表(这么说其实不严谨,但是可以比较简单理解)
- 多不用'/'封闭。大部分不使用,但是我在实际过程中由于一些框架的原因,还是使用了。我觉得风格统一就行。
- 版本号有两种风格,一种是在url中显示声明,一种是在请求的header中添加,后台服务根据header中的版本信息转交给对应的应用处理。早期的时候我用前者,它看起来非常直观,但在重构代码的时候我暂时没加版本,如果要加的话,我也觉得我会放到header中,资源本身应该是没版本的,它代表的是当下资源的状态,中小系统,设计好之后应该不会有这么多版本。如果用户请求的时候会有一些额外的需求,在header中添加,在后台灵活判断即可,github就是这种,或者改变url我觉得也是可以的。
HTTP动作表示对资源的操作
•GET(SELECT):从服务器取出资源(一项或多项)。
•POST(CREATE):在服务器新建一个资源。
•PUT(UPDATE):在服务器更新资源(需提交一个全量的data,后台重新全部赋值)。
•PATCH(UPDATE):在服务器更新资源(可以提交一个data的部分字段值,不提交的不改变)。
•DELETE(DELETE):从服务器删除资源。
get展开谈
get针对一个或者多个资源的处理
列表
访问api不加任何参数是返回列表数据,一般会分页
一般会有分页,要访问的页数和每页的条目数。返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么,比如下一页是什么。
单条资源的获取
获取一个值,需要知道id,直接在api后面加id即可
会获取id为1的数据实例,在存在的情况下会返回一个实例。这个时候不是list了大家要注意。
条件筛选
除此以外属于筛选过滤,filter,返回的会是一个列表数据。
条件过滤分两种,一种是基础的分页排序,一种是定制的。
分也排序
分页排序就是告诉系统要哪些数据,一般是page(请求第几页),page_size(每页数据量) ,order_by(按哪个字段排序),order(正序逆序)。
大同小异,这个是我比较认可的一种分页方式,也有那种offset和limit的,类似sql语句的分页,我不是很喜欢。
定制字段筛选
定制的字段就需要后台支持了,比如我们支持ip查询的话,需要后台写好处理,不是你所见到额都支持查询,如下图,必须后台支持vendor这个字段查询
事实上,做的比较好的,都会支持非常丰富的查询手段。
创建
在endpoint底下直接post数据就可以创建条目
endpoint+idata+post http方法=创建资源
比如向endpoint api/cmdb/devices/
我post一个基于json的data
{"ip": "192.168.1.1",
"name": "sh-alo-as01",
"vendor": "Cisco",
"start_u": 2,
"end_u": 3}
就会在资源层创建一个设备的资源。
删除
endpoint+id +delete http方法=删除资源
比如我向api/cmdb/devices/1 发送一个delete请求,我就会把这个设备删除掉
大家有感受到表现层的状态转移吗?就是资源发生了变化。事实告诉我们一定要学会高大上的词汇。
比如你抽筋了不要说抽筋,要说自己有不经意间肌肉无意识自主收缩症。。。嗯耍宝结束继续。。。
更新
endpoint+id + data+put patch http方法=更新资源
更新需要提供你更新的数据的id值,以及需要更新的数据
比如在1的设备未被删除时,向api/cmdb/devices/1发送一个put请求
{"ip": "192.168.1.1",
"name": "sh-alo-as01-new",
"vendor": "Cisco",
"start_u": 2,
"end_u": 3}
这个设备的名称就会发生变化了,哦不对,这个资源的表现层发生了状态转移!
put方法必须每个字段都赋值,发送给endpoint。
patch可以只发需要修改的部分。
api的接发数据多为json格式,但是,不绝对,xml也可以。
以状态码为核心的操作的结果表示
以上的是操作,操作完了 RESTful 风格的api会返回你操作的结果,以HTTP状态码为核心。
哦,有说错了,是告诉你资源表现层发生了哪些状态转移。
大类
2XX代表成功
4XX代表请求端请求的数据有问题
5XX代表服务器端有异常
常见的几种状态码
200 代表ok 多为查询时用
201 创建更新成功 会把创建或者更新后的数据返回
204 删除成功(删除) 返回的body为空,即时你显示声明了内容,也基本是空,没有内容,至少在浏览器里是这样,所以也不用打印一下信息在body里。
400 请求的参数不太规范导致查询失败
401 未认证
403 权限不够
404 资源不存在,多指查询失败
500 服务器不行了
除了204的2XX 或者4XX 5XX,多会在body里放一些其他信息,比如成功或者失败异常的原因。
小结
以上就是今天所讲,就先写这些吧,通过一些实际去讲解RESTful风格的API是什么鬼东西,当然我的认知也是拾人牙慧或者自己的无知解读,欢迎指正。
指正请去知乎,我的公众号暂时不支持留言。。。申请的太晚了。
本来想水一篇,结果又写了2500多字。。。嗯 不过还是挺水的。
下一篇,讲讲怎么用requests模块去操作数据,或者操作设备。
微信公众号:NetDevOps加油站,欢迎你的加入!
论文:https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm