restful架构风格设计准则资源识别和资源设计

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了restful架构风格设计准则资源识别和资源设计相关的知识,希望对你有一定的参考价值。

restful风格的设计中,首先要识别系统中的资源,然后用HTTP规范表示这些资源。

一、资源识别

1、以资源为中心 vs 以动作为中心

以动作为中心

在传统的软件分析设计中,常常要分析业务要使用的业务逻辑,并为业务逻辑的执行提供一系列接口。如:将商品放入购物车,提交订单等。这一系列接口组合在一起就可以组成完成目标所需要执行的业务逻辑。

在需要调用这些接口的时候,软件开发人员需要向这些接口所在的URL发送一个请求,从而驱使服务执行该动作。

以资源为中心

而在restful风格的软件分析设计中,我们所提供的各个接口则需要是一系列资源,而业务逻辑需要通过对资源的操作来完成。

也就是说,REST服务中的API将不再以执行了什么动作为中心,而是以资源为中心。一些对资源的通用操作有添加,取得,修改,删除,以及对符合特定条件的资源进行列表操作。

 

资源候选者:动作的宾语,看能否独立

我们再以“将商品放入购物车”这个操作为例。

在一个REST系统中,购物车将被抽象为一个资源,而“将商品放入购物车”这个操作将被解释为对购物车这个资源的更新:更新购物车,以使特定商品包含在购物车内。

这种描述方法的不再以动作为中心,而是以资源为中心。与之对应的是系统设计步骤的改变:我们将不再首先是别完成业务逻辑所需的各动作,而是支持业务逻辑所需要的各资源。

那么我们应该如何抽象出这些资源呢?首先,我们对某个操作不要再关注它所执行的动作,而是关心它所操作的宾语。通常情况下,该宾语就会是REST系统中的资源。

 

资源候选者:资源包含的信息,如果被系统中其他资源使用,就可能是潜在的资源

在这里,我们就以“提交订单”作为示例来展示如何抽象资源。

首先,在“提交订单”这个动作中,订单是宾语。因此对于该业务逻辑,其将作为一个资源存在。

除此之外,在订单中还需要包含一系列信息,例如订单中所包含的商品,订单所属人等。一旦这些都可以被该REST系统中的其它资源使用,那么它们也将成为独立的资源。

 

 

资源候选者:变化的实体

有时候一个动作可能并不存在着它所操作的宾语。在这种情况下,我们就需要考虑该动作产生或消除了哪个实体,或者哪个实体的状态发生了变化。这个发生了变化的实体实际上就是一种资源。

例如对于登陆这一行为,其实际上在服务端创建了一个会话实例。该会话实例中则包含了登陆IP,登陆时间,以及登陆时所用的凭证等。再比如对于用户更改密码这种行为,其所操作的资源就是用户资料。

 

找到主资源

在抽象资源的过程中,我们需要按照自顶向下的方式,即首先辨识出系统中的最主要资源,然后再辨识这些主要资源的子资源,并依次进行迭代。

对主资源的抽取主要通过分析业务逻辑来完成。在得到功能需求以后,我们首先要分析这些业务逻辑所操作的宾语。这些宾语可能有两种情况:主资源或者其它资源的子资源。主资源实际上就是能够独立存在的一系列资源。而子资源则需要依附于主资源之上才能表达实际的意义。同时各个子资源也可能拥有自身的子资源。

 

依次识别子资源

判断一个资源是否是子资源的一个方法就是看它是否能独立地表示其具体含义。例如对于一个egoods上所销售的商品,其名称,价格,简介等属性可以清晰地描述该商品到底是什么,到底如何销售。因此这些商品实际上是一个主资源。但是每种商品所支持的邮递服务需要是一个子资源:一个商品可以支持多种邮递服务。这些邮递服务根据派送距离等需要不同的价格,也提供了不同的邮递速度。由于这些邮递服务与商家和邮递服务公司所达成的服务价格有关,并且会由于商品重量的变化而变化,因此这些邮递服务并不能为其它商家所提供的邮递服务作为参考,因此其应该作为该商品的一个子资源。

或者也可以说,如果一个资源是主资源,那么其可以被不同的资源实例包含引用而不会产生歧义。而如果一个资源是子资源,那么被不同的资源实例引用可能会产生歧义。

但是需要注意的是,一种资源可能有多种不同的表现形式。例如对于在使用列表展示各个商品的时候,egoods只需要展示商品的名称,一个对该商品的简单描述,商品的价格以及一张商品的照片。而在用户打开了该商品页之后,页面则需要显示更详尽的信息,如商品的重量,商品所在地等等。

除此之外,资源列表也有可能拥有多种不同的表现形式。举例来说,如果egoods上属于某个分类的商品太多,需要分页显示,那么这种分页是否也应该是一种资源?答案是,这些分页并不是一种资源,而其只是资源列表的一种表现方式。在每页所包含商品数量,排序规则等条件发生变化的时候,该资源列表中所包含的各个商品也会发生变化。

那么如何判断我们为REST服务所定义的资源是否合理呢?一般情况下,我都使用下面的一些判断方法:

  首先,我们需要考虑对该资源的CRUD是否有意义,从而验证资源的定义是否合理。就以刚刚说到的列表的分页显示为例,我们可以想象一下如何对分页进行添加和删除?一旦删除了该分页,那么属于该分页中的各个商品也应该被删除么?而且删除了分页X的数据后,原本X + 1分页的数据将展示在X分页中。很显然,将商品的分页定义为资源并不合理。

  其次,我们需要检查资源是否需要除CRUD之外的动词来操作。该方法用来检查资源中是否还有子资源没有被抽象。如果该资源还需要额外的动词,那么我们就需要考虑这些操作到底引起了什么样的状态变化,进而抽象出该资源的子资源。

  除此之外,我们还需要检查这些资源是否是被整体使用,创建和删除。该方法用来探测是否一个子资源应该是一个主资源。如果在删除一个资源的时候,其子资源还可以被其它资源重用,那么该子资源实际上具有较高的重用性,应该是一个主资源。

二、资源设计

以上是关于restful架构风格设计准则资源识别和资源设计的主要内容,如果未能解决你的问题,请参考以下文章

restful架构风格设计准则版本管理

RESTful Webservice 概念

RESTFUL

webservice和restful的区别

SOAP Webservice和RESTful Webservice

restquestmapping里面有多少种参数,都有啥作用