restFul的趣味理解

*今天偶尔在简书上读到一个作者解释restFul解释的风趣,且好理解。分享给大家~*

Level0 面向前台

比如你要去星巴克前台点单一杯拿铁,这个过程,我们可以用简单的json字符串来实现:
	{
    "addorder":{
        "orderName":"latte"
    }
}

这个字符串代表我们需要点单一杯拿铁。
接着前台返回给我们:

{
    "orderId":"123456"
}

这个返回结果,代表您的定单编号是:123456,等下叫号取参。

突然想起自己有会员卡,所以又向前台发出一个问题:

"queryBalance": {
        "cardId": "88886666"
    }
}

查询会员卡余额,会员卡号是:88886666
查询结果返回来:

{
    "balance": "0"
}

没成想自己是个屌丝,所有的卡中存款余额都是0,包括口袋,这可咋整,付不起拿铁了~
接着就向前台发送请求

{
    "deleteOrder": {
        "orderId": "123456"
    }
}

请删除这个定单,定单号为:123456

Level1 面向资源

星巴克越做越大,一开始前台既点单收费又做餐的,现在老板决定多招些员工,专人专用。
点单的人专门负责点单和收费。
做餐的人专门负责做咖啡。
所以我的请求变为:

/orders

{
    "addOrder": {
        "orderName": "latte"
    }
}

多了个/orders什么意思呢?
意思是,我们发送的请求是对着点单的人员的,他可以帮我们处理所有有关订单的操作,包括新增订单、修改订单、取消订单等操作,也就是面向资源的请求。
返回依旧是:

{
   "orderId":"123456"
}

下面,我们还是要查询会员卡余额,这次请求的资源变成了cards

/cards

{
    "queryBalance": {
        "cardId": "886333"
    }
}

“接下来是取消订单”
/orders

{
“deleteOrder”: {
“orderId”: “123456”
}
}

清楚了吧。这就是面向资源的请求。

Level2 - 打上标签

“接下来,店主还想继续优化他的咖啡厅的服务流程,他发现负责处理订单的员工,每次都要去订单内容里面看是新增订单还是删除订单,还是其他的什么操作,十分不方便,于是规定,所有新增资源的请求,都在请求上面写上大大的‘POST’,表示这是一笔新增资源的请求”

“其他种类的请求,比如查询类的,用‘GET’表示,删除类的,用‘DELETE’表示”

“还有修改类的,修改分为两种,第一种,如果这个修改,无论发送多少次,最后一次修改后的资源,总是和第一次修改后的一样,比如将拿铁改为猫屎,那么用‘PUT’表示;第二种,如果这个修改,每次修改都会让这个资源和前一次的不一样,比如是加一杯咖啡,那么这种请求用‘PATCH’或者‘POST’表示”.
点单:

POST /orders
{
    "orderName": "latte"
} 

返回值相同
接着是查询会员卡余额

GET /cards

{
    "cardId": "886333"
}

还可以改为:

GET /cards/886333

继续,取消订单

DELETE /orders/123456

Level3 完美服务

“忽然有一天,有个顾客抱怨说,他买了咖啡后,不知道要怎么取消订单,咖啡厅一个店员回了一句,你不会看我们的宣传单吗,上面不写着:

DELETE /orders/{orderId}

顾客反问道,谁会去看那个啊,店员不服,又说到,你瞎了啊你…据说后面两人吵着吵着还打了起来…”
“噗,真是悲剧…”
“有了这次教训,店长决定,顾客下了单之后,不仅给他们返回订单的编号,还给顾客返回所有可以对这个订单做的操作,比如告诉用户如何删除订单。现在,我们还是发出请求,请求内容和上一次一样”

POST /orders

{
    "orderName": "latte"
}

但是这次返回时多了些内容”

{
    "orderId": "123456",
    "link": {
        "rel": "cancel",
        "url": "/order/123456"
    }
}

“这次返回时多了一项link信息,里面包含了一个rel属性和url属性,rel是relationship的意思,这里的关系是cancel,url则告诉你如何执行这个cancel操作,接着你就可以这样子来取消订单啦”

DELETE /orders/123456

上面讲的Level0~Level3,来自Leonard Richardson提出的Richardson Maturity Model:
在这里插入图片描述

Level0和Level1最大的区别,就是Level1拥有了Restful的第一个特征——面向资源,这对构建可伸缩、分布式的架构是至关重要的。同时,如果把Level0的数据格式换成Xml,那么其实就是SOAP,SOAP的特点是关注行为和处理,和面向资源的RESTful有很大的不同。
Level0和Level1,其实都很挫,他们都只是把HTTP当做一个传输的通道,没有把HTTP当做一种传输协议。

Level2,真正将HTTP作为了一种传输协议,最直观的一点就是Level2使用了HTTP动词,GET/PUT/POST/DELETE/PATCH…,这些都是HTTP的规范,规范的作用自然是重大的,用户看到一个POST请求,就知道它不是幂等的,使用时要小心,看到PUT,就知道他是幂等的,调用多几次都不会造成问题,当然,这些的前提都是API的设计者和开发者也遵循这一套规范,确保自己提供的PUT接口是幂等的。

Level3,关于这一层,有一个古怪的名词,叫HATEOAS(Hypertext As The Engine Of Application State),中文翻译为“将超媒体格式作为应用状态的引擎”,核心思想就是每个资源都有它的状态,不同状态下,可对它进行的操作不一样。理解了这一层,再来看看REST的全称,Representational State Transfer,中文翻译为“表述性状态转移”,是不是好理解多了?

Level3的Restful API,给使用者带来了很大的便利,使用者只需要知道如何获取资源的入口,之后的每个URI都可以通过请求获得,无法获得就说明无法执行那个请求。

现在绝大多数的RESTful接口都做到了Level2的层次,做到Level3的比较少。当然,这个模型并不是一种规范,只是用来理解Restful的工具。所以,做到了Level2,也就是面向资源和使用Http动词,就已经很Restful了。Restful本身也不是一种规范,我比较倾向于用"风格"来形容它。如果你想深入了解Level3,可以阅读《Rest in Practice》第五章。

Big things have small beginnings.大物始于小。

参考作者:如何给老婆解释什么是restful ——柳树之

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章