读书笔记,原文链接: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架构风格设计准则(三)资源识别和资源设计的更多相关文章

  1. restful架构风格设计准则(二)以资源为中心,一个url

    读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 1.REST是一种架构风格,其核心是面向资源,简化设计,降低开发的复杂性 ...

  2. restful架构风格设计准则(一)以资源为中心、自描述的请求响应、资源状态迁移为粒度

    读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 一.需求描述 当用户在某个电子商务网站购物时,他首先查看要购买的商品分类 ...

  3. restful架构风格设计准则(四)资源表示和资源访问

    读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 一.资源表示 1.资源表示:使用 单数 vs. 复数 如果一个URL所对 ...

  4. restful架构风格设计准则(六)版本管理

    读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 版本管理 在前面已经提到过,一个REST系统为资源所抽象出的URI实际上 ...

  5. restful架构风格设计准则(五)用户认证和session管理

    读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! Authentication REST提倡无状态约束,这就要求:用户状态 ...

  6. RESTful 架构风格

    在移动互联网的大潮下,『微服务』的概念也越来越被大家接受并应用于实践,日益增多的web service逐渐统一于RESTful 架构风格,如果开发者对RESTful 架构风格不甚了解,则开发出的所谓R ...

  7. 【转载】RESTful 架构风格概述

    本文转载自https://blog.igevin.info/posts/restful-architecture-in-general/ 在移动互联网的大潮下,随着docker等技术的兴起,『微服务』 ...

  8. 论单页Web应用和RESTful架构

    单页Web应用 概述 单页Web应用并不是突然诞生的一门新技术,而是web展示的一种新的尝试.它将所有的动作局限于一个Web页面,在加载站点首页的时候就加载站点需要的JavaScript和CSS.单页 ...

  9. Web应用和RESTful架构

    Web应用和RESTful架构 单页Web应用 概述 单页Web应用并不是突然诞生的一门新技术,而是web展示的一种新的尝试.它将所有的动作局限于一个Web页面,在加载站点首页的时候就加载站点需要的J ...

随机推荐

  1. WebService下实现大数据量的传输

    设置RemotingFormat = SerializationFormat.Binary;再序列化,通过WebService传输,客户端接收,再反序列化,确实效果大大的优于直接传送DataSet,不 ...

  2. Redis 基础(一)

    Remote Dictionary Server(Redis)是一个由Salvatore Sanfilippo写的key-value存储系统.Redis是一个开源的使用ANSI C语言编写.遵守BSD ...

  3. ajax提交表单、ajax实现文件上传

    ajax提交表单.ajax实现文件上传,有需要的朋友可以参考下. 方式一:利用from表单的targer属性 + 隐藏的iframe 达到类似效果, 支持提交含有文件和普通数据的复杂表单 方式二:使用 ...

  4. vc的环境变量配置和缺少mspdb60.dll的解决方法

    vc的编译器是cl.exe,我们如果在vc中编译就不用配置环境,但是如果要在任何位置用命令提示符打开编译器cl.exe来编译程序,那么就要配置环境了. 下面我就讲讲vc的环境变量配置和缺少mspdb6 ...

  5. 【Unity与23种设计模式】迭代器模式(Iterator)

    GoF中定义: "在不知道集合内部细节的情况下,提供一个按序方法存取一个对象集合体的每一个单元." 迭代器模式由于经常使用到 已经被现代程序设计语言纳为标准语句或收录到标准函数库中 ...

  6. 2018世界气象日,API为气象助力

    "世界气象日"(World Meteorological Day)又称"国际气象日",是[世界气象组织]成立的纪念日. 国际气象组织的前身原为非官方性国际气象合 ...

  7. 如何给自己的外包APP开发报价?

    作者:CODING 兄弟,你看做这样一个软件需要多少钱?" 这估计是所有软件从业人员被问的最多也是最无奈的一个问题.这个问题等同于,"你看装修一个100平米的房子需要多少钱?&qu ...

  8. 第八届蓝桥杯省赛17【java B组】第一题

    1,标题: 购物单    小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞.    这不,XX大促销又来了!老板夫人开出了长长的购 ...

  9. MSIL实用指南-生成索引器

    MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...

  10. Kali Linux下安装Nessus扫描器

    一.官网下载Nessus(http://www.tenable.com/products/nessus/select-your-operating-system),这里需要查找自己对应的版本,如下图一 ...