restful架构风格设计准则(三)资源识别和资源设计
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者!
restful风格的设计中,首先要识别系统中的资源,然后用HTTP规范表示这些资源。
一、资源识别
1、以资源为中心 vs 以动作为中心
1.1、以动作为中心
在传统的软件分析设计中,常常要分析业务要使用的业务逻辑,并为业务逻辑的执行提供一系列接口。如:将商品放入购物车,提交订单等。这一系列接口组合在一起就可以组成完成目标所需要执行的业务逻辑。在需要调用这些接口的时候,软件开发人员需要向这些接口所在的URL发送一个请求,从而驱使服务执行该动作。
1.2、以资源为中心
在restful风格的软件分析设计中,我们所提供的各个接口则需要是一系列资源,而业务逻辑需要通过对资源的操作来完成。REST服务中的API将不再以执行了什么动作为中心,而是以资源为中心。一些对资源的通用操作有添加,修改,删除, 获取,以及对符合特定条件的资源进行列表操作。
2、资源候选者
2.1、找到主资源
资源候选者:动作的宾语,看能否独立
我们再以“将商品放入购物车”这个操作为例。
在一个REST系统中,购物车将被抽象为一个资源,而“将商品放入购物车”这个操作将被解释为对购物车这个资源的更新:更新购物车,以使特定商品包含在购物车内。
这种描述方法的不再以动作为中心,而是以资源为中心。与之对应的是系统设计步骤的改变:我们将不再首先是别完成业务逻辑所需的各动作,而是支持业务逻辑所需要的各资源。
那么我们应该如何抽象出这些资源呢?首先,我们对某个操作不要再关注它所执行的动作,而是关心它所操作的宾语。通常情况下,该宾语就会是REST系统中的资源。
资源候选者:资源包含的信息,如果被系统中其他资源使用,就可能是潜在的资源
在这里,我们就以“提交订单”作为示例来展示如何抽象资源。
首先,在“提交订单”这个动作中,订单是宾语。因此对于该业务逻辑,其将作为一个资源存在。
除此之外,在订单中还需要包含一系列信息,例如订单中所包含的商品,订单所属人等。一旦这些都可以被该REST系统中的其它资源使用,那么它们也将成为独立的资源。
资源候选者:变化的实体
有时候一个动作可能并不存在着它所操作的宾语。在这种情况下,我们就需要考虑该动作产生或消除了哪个实体,或者哪个实体的状态发生了变化。这个发生了变化的实体实际上就是一种资源。
例如对于登陆这一行为,其实际上在服务端创建了一个会话实例。该会话实例中则包含了登陆IP,登陆时间,以及登陆时所用的凭证等。再比如对于用户更改密码这种行为,其所操作的资源就是用户资料。
2.2、依次识别子资源
找到主资源
在抽象资源的过程中,我们需要按照自顶向下的方式,即首先辨识出系统中的最主要资源,然后再辨识这些主要资源的子资源,并依次进行迭代。
对主资源的抽取主要通过分析业务逻辑来完成。在得到功能需求以后,我们首先要分析这些业务逻辑所操作的宾语。
这些宾语可能有两种情况:主资源或者其它资源的子资源。主资源实际上就是能够独立存在的一系列资源。而子资源则需要依附于主资源之上才能表达实际的意义。同时各个子资源也可能拥有自身的子资源。
依次识别子资源
判断一个资源是否是子资源的一个方法就是看它是否能独立地表示其具体含义。例如对于一个egoods上所销售的商品,其名称,价格,简介等属性可以清晰地描述该商品到底是什么,到底如何销售。因此这些商品实际上是一个主资源。但是每种商品所支持的邮递服务需要是一个子资源:一个商品可以支持多种邮递服务。这些邮递服务根据派送距离等需要不同的价格,也提供了不同的邮递速度。由于这些邮递服务与商家和邮递服务公司所达成的服务价格有关,并且会由于商品重量的变化而变化,因此这些邮递服务并不能为其它商家所提供的邮递服务作为参考,因此其应该作为该商品的一个子资源。
或者也可以说,如果一个资源是主资源,那么其可以被不同的资源实例包含引用而不会产生歧义。而如果一个资源是子资源,那么被不同的资源实例引用可能会产生歧义。
2.3、如何判断为REST服务所定义的资源是否合理?
- 检查对该资源的CRUD是否有意义
- 检查资源是否需要除CRUD之外的动词来操作。该方法用来检查资源中是否还有子资源没有被抽象。如果该资源还需要额外的动词,那么我们要考虑这些操作到底引起了什么样的状态变化,进而抽象出该资源的子资源。
- 检查这些资源是否是被整体使用,创建和删除。该方法用来探测是否一个子资源应该是一个主资源。如果在删除一个资源时,其子资源还可以被其它资源重用,那么该子资源实际上具有较高的重用性,应该是一个主资源。
二、资源表示
每个资源都拥有一个资源标识,所以正确识别一个资源之后,我们就要为这些资源分配其所对应的URI。
在HTTP中,一个URL主要由四部分组成:
- 协议:http https
- 主机名和端口:www.taobao.com:8080
- 资源的相对路径:/API/categories
- 请求参数:即由问号开始的由键值对组成的字符串:?page=1&page_size=20
通过URL来表示资源: 在识别出REST系统中的各个资源后,我们需要为这些资源设计各自所对应的URL。
1、所有的资源都应该存在于一个相对路径之下
GET /API
Host: www.xxx.com
Authorization: Basic xxxxxxxxxxxxxxxxxxx
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: xxx
{
"version": "1.0",
"resources": [
{
"label" : "Categories",
"description" : "Product categories",
"uri": "/API/categories"
}, {
"label" : "Items",
"description" : "All items on sell",
"uri": "/API/items"
}
]
}
因此对于从向该相对路径发送请求才能得到的各个主资源来说,将它们置于相对路径/API之下是非常合理的。
除了这个原因之外,API的版本更迭也是一个考虑。假如软件开发人员需要开发一个新版本的REST API,那么他可能就需要重新抽象并定义系统中的各个资源。
但是如果两个版本的API中都拥有一个categories资源,并且系统为了保持后向兼容性同时保留了两个版本的API,那么将只有一个资源可以使用/categories这个相对路径。
正因为如此,将这些资源置于相对路径/API之下,并在第二个版本的API出现之后将新的资源抽象置于/API-v2下是一种较为流行的做法。
2、主资源所对应的URL
主资源是一类独立的资源,因此它应该直接置于/API下。
例如:
- xxx网站中的产品分类是一个主资源,我们可以为其分配URL:/API/categories。
- xxx网站中的产品也是一个主资源,我们可以为其分配URL:/API/items
这样,每类主资源都将拥有一个特定于该类资源的URL。这些URL就对应着相应资源实例的集合。
3、主资源类型的特定实例的URL=该类主资源所对应URL后添加该实例ID
例如:xxx网站中的食品分类的ID为1,其对应URL:/API/categories/1
对于某种类型的主资源,整个系统将有且仅有一个该类型资源的实例,那么该资源实例将不需要通过ID来访问。如:对整个系统进行介绍的资源,该资源实例所对应的URL:/API/about
4、主资源实例下的子资源的URL
一个资源实例中还可能拥有子资源。这些子资源与资源实例之间的关系主要有两种情况:
- 资源实例包含了一个子资源的集合,如:对于ID为23456的商品所提供的邮递服务,使用URL:/API/items/23456/shipments,其中一个ID为87256的邮递服务所对应的URI则为:/API/items/23456/shipments/87256
- 资源实例仅仅可以包含一个子资源,如:当前商品的折扣信息:/API/items/23456/discount
restful架构风格设计准则(三)资源识别和资源设计的更多相关文章
- restful架构风格设计准则(二)以资源为中心,一个url
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 1.REST是一种架构风格,其核心是面向资源,简化设计,降低开发的复杂性 ...
- restful架构风格设计准则(一)以资源为中心、自描述的请求响应、资源状态迁移为粒度
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 一.需求描述 当用户在某个电子商务网站购物时,他首先查看要购买的商品分类 ...
- restful架构风格设计准则(四)资源表示和资源访问
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 一.资源表示 1.资源表示:使用 单数 vs. 复数 如果一个URL所对 ...
- restful架构风格设计准则(六)版本管理
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 版本管理 在前面已经提到过,一个REST系统为资源所抽象出的URI实际上 ...
- restful架构风格设计准则(五)用户认证和session管理
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! Authentication REST提倡无状态约束,这就要求:用户状态 ...
- RESTful 架构风格
在移动互联网的大潮下,『微服务』的概念也越来越被大家接受并应用于实践,日益增多的web service逐渐统一于RESTful 架构风格,如果开发者对RESTful 架构风格不甚了解,则开发出的所谓R ...
- 【转载】RESTful 架构风格概述
本文转载自https://blog.igevin.info/posts/restful-architecture-in-general/ 在移动互联网的大潮下,随着docker等技术的兴起,『微服务』 ...
- 论单页Web应用和RESTful架构
单页Web应用 概述 单页Web应用并不是突然诞生的一门新技术,而是web展示的一种新的尝试.它将所有的动作局限于一个Web页面,在加载站点首页的时候就加载站点需要的JavaScript和CSS.单页 ...
- Web应用和RESTful架构
Web应用和RESTful架构 单页Web应用 概述 单页Web应用并不是突然诞生的一门新技术,而是web展示的一种新的尝试.它将所有的动作局限于一个Web页面,在加载站点首页的时候就加载站点需要的J ...
随机推荐
- redis笔记总结之redis介绍
一.Redis介绍: redis的发展历史简单的理解为因为使用类似MySql这类关系型数据库不方便进而开发的开源的.轻量级的.非关系型的,直到现在一直不断完善的一款NoSql数据库.具体的介绍大家可以 ...
- 关于Sql server数据 MD5加密
最近在写一个web项目时,需要在数据库中将用户密码等一类信息进行加密处理.数据加密算法有许多 ,各有各的优缺点;在 http://www.cnblogs.com/yangywyangyw/arch ...
- Linux epoll源码--
Linux系统运行源码剖析-epoll代码注释 理解了中断.等待队列.调度,你就能懂Linux的80%. --老子 转发的话,请注明出处哦:http://www.cnblogs.com/stoneha ...
- 11 个简单的 Java 性能调优技巧
大多数开发人员理所当然地以为性能优化很复杂,需要大量的经验和知识.好吧,不能说这是完全错误的.优化应用程序以获得最佳性能不是一件容易的事情.但是,这并不意味着如果你不具备这些知识,就不能做任何事情.这 ...
- 初尝Eclipse
一.选择开发工具 1.Eclipse和JDK 我所选用的是Eclipse开发工具,此工具可以用来编译JAVA语言,但windows系统没有内置的JAVA运行环境,所以需要下载JDK,用来配置JAVA的 ...
- ------- Tor 源码分析第三部分—— 日志设施与智能链表 --------
------------------------------------------------------------------------------------ init_logging()( ...
- 原生js写的flybird小游戏
游戏地址:http://zangzhihong.jusukeji.com/flybird/index.html html部分 <!DOCTYPE html> <!-- This ...
- java函数回调
Class A实现接口CallBack callback--背景1 class A中包含一个class B的引用b --背景2 class B有一个参数为callback的方法f(CallBack c ...
- Druid数据库连接池就这么简单
前言 本章节主要讲解Druid数据库连接池,为什么要学Druid数据库连接池呢?? 我的知识储备数据库连接池有两种->C3P0,DBCP,可是现在看起来并不够用阿~当时学习C3P0的时候,觉得这 ...
- STL --> find()和find_if()
find()和find_if() 一.find()函数 find(first, end, value); // 返回区间[first,end)中第一个值等于value的元素的位置.如果没有找到匹配元素 ...