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不加任何参数是返回列表数据,一般会分页

究竟什么是RESTful风格API_数据

一般会有分页,要访问的页数和每页的条目数。返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么,比如下一页是什么。

单条资源的获取

获取一个值,需要知道id,直接在api后面加id即可

究竟什么是RESTful风格API_数据_02

会获取id为1的数据实例,在存在的情况下会返回一个实例。这个时候不是list了大家要注意。

条件筛选

除此以外属于筛选过滤,filter,返回的会是一个列表数据。

条件过滤分两种,一种是基础的分页排序,一种是定制的。

分也排序

分页排序就是告诉系统要哪些数据,一般是page(请求第几页),page_size(每页数据量) ,order_by(按哪个字段排序),order(正序逆序)。

大同小异,这个是我比较认可的一种分页方式,也有那种offset和limit的,类似sql语句的分页,我不是很喜欢。

定制字段筛选

定制的字段就需要后台支持了,比如我们支持ip查询的话,需要后台写好处理,不是你所见到额都支持查询,如下图,必须后台支持vendor这个字段查询

究竟什么是RESTful风格API_REST_03

事实上,做的比较好的,都会支持非常丰富的查询手段。

创建

在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