目录

什么是REST

REST架构约束

REST资源命名指南

REST资源命名最佳实践

使用名词来表示资源

一致性是关键

永远不要在URI中使用CRUD函数名称

使用查询组件过滤URI集合


什么是REST

REST是RE表示S tate T ransfer的首字母缩写。它是分布式超媒体系统的架构风格,最初由Roy Fielding在2000年的着名论文中提出。

与任何其他架构风格一样,REST也有自己的6个引导约束,如果接口需要被称为RESTful,则必须满足这些约束。这些原则如下。

REST的指导原则

  1. 客户端 - 服务器 - 通过将用户界面问题与数据存储问题分开,我们提高了跨多个平台的用户界面的可移植性,并通过简化服务器组件来提高可扩展性。
  2. 无状态 - 从客户端到服务器的每个请求都必须包含理解请求所需的所有信息,并且不能利用服务器上任何存储的上下文。因此,会话状态完全保留在客户端上。
  3. 可缓存 - 缓存约束要求将对请求的响应中的数据隐式或显式标记为可缓存或不可缓存。如果响应是可缓存的,则客户端缓存有权重用该响应数据以用于以后的等效请求。
  4. 统一接口 - 通过将通用性的软件工程原理应用于组件接口,简化了整个系统架构,提高了交互的可见性。为了获得统一的接口,需要多个架构约束来指导组件的行为。REST由四个接口约束定义:资源识别; 通过陈述来处理资源; 自我描述性的信息; 并且,超媒体作为应用程序状态的引擎。
  5. 分层系统 - 分层系统风格允许通过约束组件行为来使体系结构由分层层组成,这样每个组件都不能“看到”超出与它们交互的直接层。
  6. 按需代码(可选) - REST允许通过以小程序或脚本的形式下载和执行代码来扩展客户端功能。这通过减少预先实现所需的功能数量来简化客户端。

资源

REST中信息的关键抽象是一种资源。可以命名的任何信息可以是资源:文档或图像,临时服务,其他资源的集合,非虚拟对象(例如,人)等。REST使用资源标识符来标识组件之间交互中涉及的特定资源。

任何特定时间戳的资源状态称为资源表示。表示由数据,描述数据的元数据和超媒体链接组成,这些链接可以帮助客户转换到下一个期望的状态。

表示的数据格式称为媒体类型。媒体类型标识定义如何处理表示的规范。真正的RESTful API看起来像超文本。每个可寻址信息单元明确地(例如,链接和id属性)或隐式地(例如,从媒体类型定义和表示结构导出)携带地址。

根据罗伊菲尔丁的说法:

超文本(或超媒体)意味着信息和控制同时呈现,使得信息成为用户(或自动机)通过其获得选择和选择动作的可供性。请记住,超文本不需要是浏览器上的HTML(或XML或JSON)。机器在了解数据格式和关系类型时可以跟踪链接。

此外,资源表示应该是自描述的:客户端不需要知道资源是员工还是设备。它应该基于与资源相关的媒体类型。因此在实践中,您最终会创建大量自定义媒体类型 - 通常是与一种资源相关联的一种媒体类型。

每种媒体类型都定义了默认处理模型。例如,HTML定义了超文本的呈现过程以及每个元素周围的浏览器行为。它与资源方法GET / PUT / POST / DELETE / ...没有任何关系,除了一些媒体类型元素将定义一个过程模型,其类似于“具有href属性的锚元素创建一个超文本链接,当被选中时,在与CDATA编码的href属性对应的URI上调用检索请求(GET)。“

资源方法

与REST相关的其他重要事项是用于执行所需转换的资源方法。许多人错误地将资源方法与HTTP GET / PUT / POST / DELETE方法联系起来。

Roy Fielding从未提及任何关于在哪种情况下使用哪种方法的建议。他强调的是它应该是统一的界面。如果你决定HTTP POST将用于更新资源 - 而不是大多数人推荐HTTP PUT - 它没关系,应用程序界面将是RESTful。

理想情况下,更改资源状态所需的所有内容都应该是该资源的API响应的一部分 - 包括方法以及它们将保留表示的状态。

应输入REST API,除了初始URI(书签)和适用于目标受众的标准化媒体类型集之外没有任何先验知识(即,任何可能使用API​​的客户都应该理解)。从那时起,所有应用程序状态转换必须由客户端选择服务器提供的选择来驱动,这些选择存在于接收的表示中或者由用户对这些表示的操纵所暗示。转换可以由客户端对媒体类型和资源通信机制的知识来确定(或限制),这两者都可以在运行中(例如,按需代码)进行改进。
[失败在这里意味着带外信息正在推动交互,而不是超文本。]

在构建RESTful API时,另一件可以帮助您的是基于查询的API结果应该由带有摘要信息的链接列表表示,而不是由原始资源表示的数组表示,因为查询不能替代资源标识。

REST和HTTP不一样!!

很多人更喜欢将HTTP与REST进行比较。REST和HTTP不一样。

REST!= HTTP

虽然,因为REST还打算使web(互联网)更加简化和标准化,他主张更严格地使用REST原则。这就是人们试图开始将REST与网络(HTTP)进行比较的地方。Roy fielding在他的论文中没有提到任何实现指令 - 包括任何协议首选项和HTTP。到时候,您正在遵循REST的6个指导原则,您可以将您的界面称为RESTful。

简而言之,在REST架构风格中,数据和功能被视为资源,并使用统一资源标识符(URI)进行访问。通过使用一组简单,定义明确的操作来处理资源。客户端和服务器通过使用标准化接口和协议(通常是HTTP)来交换资源的表示。

资源与其表示分离,以便可以以各种格式访问其内容,例如HTML,XML,纯文本,PDF,JPEG,JSON等。例如,可以使用和使用关于资源的元数据来控制高速缓存,检测传输错误,协商适当的表示格式,以及执行认证或访问控制。最重要的是,与资源的每次交互都是无状态的。

所有这些原则都有助于RESTful应用程序简单,轻便,快速。

REST架构约束

REST代表Re presentational S tate T ransfer,这是Roy Fielding在2000年创造的一个术语。它是一种用于通过HTTP设计松散耦合应用程序的架构风格,通常用于Web服务的开发。REST没有强制执行任何有关如何在较低级别实现它的规则,它只是提出了高级设计指南,让您考虑自己的实现。

在我上一次工作中,我为电信大公司设计了RESTful API已有两年了。在这篇文章中,我将分享我的想法,除了正常的设计实践。你可能不同意我的几点,这是完全可以的。我很乐意以开放的心态与您讨论任何事情。

让我们从标准设计特定的东西开始,以清除'Roy Fielding'希望我们构建的内容。然后我们将讨论我在设计RESTful API时更加注重细节的东西。

建筑约束

REST定义了6个架构约束,它们构成了任何Web服务 - 一个真正的RESTful API。

  1. 统一界面
  2. 客户端服务器
  3. 无状态
  4. 可缓存
  5. 分层系统
  6. 按需代码(可选)

统一界面

由于约束名称本身适用,您必须为系统内部的资源决定API接口,这些资源暴露给API消费者并且遵循宗教信仰。系统中的资源应该只有一个逻辑URI,并且应该提供获取相关或附加数据的方法。将资源与网页同步化总是更好。

任何单个资源都不应该太大,并且在其表示中包含每个和所有内容。只要相关,资源应包含指向相对URI的链接(HATEOAS)以获取相关信息。

此外,跨系统的资源表示应遵循某些指导原则,如命名约定,链接格式或数据格式(xml或/和json)。

所有资源都应该通过HTTP GET等通用方法访问,并使用一致的方法进行类似修改。

一旦开发人员熟悉了您的某个API,他就应该能够对其他API采用类似的方法。

客户端服务器

这实质上意味着客户端应用程序和服务器应用程序必须能够单独进化而不相互依赖。客户端应该只知道资源URI,这就是全部。今天,这是Web开发中的常规做法,因此您无需花费任何精力。把事情简单化。

服务器和客户端也可以独立替换和开发,只要它们之间的接口不被改变即可。

无状态

Roy fielding从HTTP获得灵感,因此它反映了这种约束。使所有客户端 - 服务器交互无状态。服务器不会存储有关最新HTTP请求客户端的任何内容。它会将每个请求视为新的。没有会话,没有历史。

如果客户端应用程序需要是最终用户的有状态应用程序,用户登录一次并在此后执行其他授权操作,则来自客户端的每个请求都应包含服务请求所需的所有信息 - 包括身份验证和授权详细信息。

请求之间不应在服务器上存储客户端上下文。客户端负责管理应用程序的状态。

可缓存

在当今世界,数据和响应的缓存在任何适用/可能的地方都至关重要。您在此处阅读的网页也是HTML页面的缓存版本。缓存为客户端带来了性能改进,并为服务器提供了更好的可扩展性范围,因为负载已经减少。

在REST中,缓存应在适用时应用于资源,然后这些资源必须声明自己可缓存。缓存可以在服务器或客户端实现。

管理良好的缓存部分或完全消除了一些客户端 - 服务器交互,进一步提高了可伸缩性和性能。

分层系统

例如,REST允许您使用分层系统体系结构,在服务器A上部署API,并在服务器B上存储数据并对服务器C中的请求进行身份验证。客户端通常无法判断它是直接连接到终端服务器,还是沿途的中介。

按需代码(可选)

好吧,这个约束是可选的。大多数情况下,您将以XML或JSON的形式发送资源的静态表示。但是当您需要时,您可以自由地return executable code支持您的应用程序的一部分,例如客户可以调用您的API来获取UI小部件呈现代码。这是允许的。

以上所有限制都有助于您构建真正的RESTful API,您应该遵循它们。尽管如此,有时你可能会发现自己违反了一两个限制。别担心,您仍在制作RESTful API - 但不是“真正的RESTful”。

请注意,上述所有约束都与WWW(Web)密切相关。使用RESTful API,您可以对Web服务执行与Web页面相同的操作。

REST资源命名指南

在REST中,主数据表示称为资源。拥有强大而一致的REST资源命名策略 - 无疑将证明您是长期最佳设计决策之一。

REST中信息的关键抽象是一种资源。可以命名的任何信息都可以是资源:文档或图像,临时服务(例如“洛杉矶的今天天气”),其他资源的集合,非虚拟对象(例如人)等等。换句话说,任何可能是作者超文本引用目标的概念都必须符合资源的定义。资源是到一组实体的概念映射,而不是与任何特定时间点的映射相对应的实体。罗伊菲尔丁的论文

一个资源可以是一个单或集合。例如,“ customers”是集合资源,“ customer”是单例资源(在银行域中)。我们可以customers使用URI“ /customers” 来识别“ ”集合资源。我们可以customer使用URI“ /customers/{customerId}” 来识别单个“ ”资源。

一个资源可能包含子集的资源也。例如,可以使用URN“ ”(在银行业务域中)识别accounts特定“ customer”的子集合资源“ ” /customers/{customerId}/accounts。类似地,account子集合资源“ ”内的单个资源“ ” accounts可以如下标识:“ /customers/{customerId}/accounts/{accountId}”。

REST API使用统一资源标识符(URI)来寻址资源。REST API设计者应该创建URI,将REST API的资源模型传达给潜在的客户端开发人员。当资源命名良好时,API直观且易于使用。如果做得不好,那同样的API会感觉难以使用和理解。

统一接口的约束部分通过URI和HTTP动词的组合来解决,并且根据标准和约定使用它们。

以下是为新API创建资源URI时的一些提示。

REST资源命名最佳实践

使用名词来表示资源

RESTful URI应该引用作为事物(名词)的资源而不是引用动作(动词),因为名词具有动词不具有的属性 - 类似于具有属性的资源。资源的一些示例是:

  • 系统的用户
  • 用户帐户
  • 网络设备等

他们的资源URI可以设计如下:

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/
http://api.example.com/user-management/users/{id}

为了更清楚,让我们将资源原型划分为四个类别(文档,集合,存储和控制器),然后您应始终将资源放入一个原型,然后始终如一地使用它的命名约定为了统一,抵制设计资源的诱惑,这些资源是不止一个原型的混合体。

  1. 文献

    文档资源是一种类似于对象实例或数据库记录的单一概念。在REST中,您可以将其视为资源集合中的单个资源。文档的状态表示通常包括具有值的字段和指向其他相关资源的链接。

    使用“单数”名称表示文档资源原型。

    http://api.example.com/device-management/managed-devices/{device-id}
    http://api.example.com/user-management/users/{id}
    http://api.example.com/user-management/users/admin
  2. 采集

    集合资源是服务器管理的资源目录。客户可以建议将新资源添加到集合中。但是,要由集合选择是否创建新资源。集合资源选择它想要包含的内容,并决定每个包含的资源的URI。

    使用“复数”名称表示集合资源原型。

    http://api.example.com/device-management/managed-devices
    http://api.example.com/user-management/users
    http://api.example.com/user-management/users/{id}/accounts
  3. 商店

    商店是客户端管理的资源库。商店资源允许API客户端放入资源,将其退出,并决定何时删除它们。商店永远不会生成新的URI。相反,每个存储的资源都有一个客户端在最初放入存储时选择的URI。

    使用“复数”名称表示商店资源原型。

    http://api.example.com/cart-management/users/{id}/carts
    http://api.example.com/song-management/users/{id}/playlists
  4. 调节器

    控制器资源模拟程序概念。控制器资源就像可执行函数,带有参数和返回值; 输入和输出。

    使用“动词”表示控制器原型。

    http://api.example.com/cart-management/users/{id}/cart/checkout
    http://api.example.com/song-management/users/{id}/playlist/play

一致性是关键

使用一致的资源命名约定和URI格式,以最小化和最大可读性和可维护性。您可以实现以下设计提示以实现一致性:

  1. 使用正斜杠(/)表示层次关系

    正斜杠(/)字符用于URI的路径部分,以指示资源之间的层次关系。例如

    http://api.example.com/device-management
    http://api.example.com/device-management/managed-devices
    http://api.example.com/device-management/managed-devices/{id}
    http://api.example.com/device-management/managed-devices/{id}/scripts
    http://api.example.com/device-management/managed-devices/{id}/scripts/{id}
  2. 不要在URI中使用尾部正斜杠(/)

    作为URI路径中的最后一个字符,正斜杠(/)不会添加语义值,并可能导致混淆。最好完全放弃它们。

    http://api.example.com/device-management/managed-devices/
    http://api.example.com/device-management/managed-devices / *这是更好的版本* /
  3. 使用连字符( - )来提高URI的可读性

    要使您的URI易于扫描和解释,请使用连字符( - )字符来提高长路径段中名称的可读性。

    http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //更易读
    http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation //不太可读
  4. 不要使用下划线(_)

    可以使用下划线代替连字符作为分隔符 - 但是根据应用程序的字体,下划线(_)字符可能会在某些浏览器或屏幕中被部分遮挡或完全隐藏。

    为避免这种混淆,请使用连字符( - )而不是下划线(_)。

    http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //更易读
    http://api.example.com/inventory_management/managed_entities/{id}/install_script_location //更容易出错
  5. 在URI中使用小写字母

    方便时,URI路径中应始终首选小写字母。

    RFC 3986将URI定义为区分大小写,但方案和主机组件除外。例如

    http://api.example.org/my-folder/my-doc // 1
    HTTP://API.EXAMPLE.ORG/my-folder/my-doc // 2
    http://api.example.org/My-Folder/my-doc // 3

    在上面的例子中,1和2是相同的,但3不是因为它使用大写字母的My-Folder

  6. 不要使用文件扩展名

    文件扩展名看起来很糟糕,不会增加任何优势。删除它们也会减少URI的长度。没理由保留它们。

    除了上述原因,如果您想使用文件扩展突出显示API的媒体类型,那么您应该依赖于通过Content-Type标题传达的媒体类型来确定如何处理正文的内容。

    http://api.example.com/device-management/managed-devices.xml / *不要使用它* /
    http://api.example.com/device-management/managed-devices / *这是正确的URI * /

永远不要在URI中使用CRUD函数名称

URI不应用于指示执行CRUD功能。URI应该用于唯一标识资源,而不是对它们的任何操作。应使用HTTP请求方法来指示执行哪个CRUD功能。

HTTP GET http://api.example.com/device-management/managed-devices //获取所有设备
HTTP POST http://api.example.com/device-management/managed-devices //创建新设备HTTP GET http://api.example.com/device-management/managed-devices/{id} //获取给定标识的设备
HTTP PUT http://api.example.com/device-management/managed-devices/{id} //更新给定标识的设备
HTTP DELETE http://api.example.com/device-management/managed-devices/{id} //删除给定标识的设备

使用查询组件过滤URI集合

很多时候,您会遇到需要根据某些特定资源属性对需要排序,过滤或限制的资源集合的要求。为此,请不要创建新的API - 而是

在资源集合API中启用排序,过滤和分页功能,并将输入参数作为查询参数传递。例如

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices?region=USA
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date

参考文献:

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven 
http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm

Rest——分布式超媒体系统的架构风格相关推荐

  1. python分布式爬虫系统_三种分布式爬虫系统的架构方式

    分布式爬虫系统广泛应用于大型爬虫项目中,力求以最高的效率完成任务,这也是分布式爬虫系统的意义所在. 分布式系统的核心在于通信,介绍三种分布式爬虫系统的架构思路,都是围绕通信开始,也就是说有多少分布式系 ...

  2. (转)架构风格与基于网络的软件架构设计(介绍REST)

    随着软件水平在国内的发展,中国程序员的水平也逐渐的在提高,从当年英雄式,到后来的软件作坊,现在越来越多的人开始关注软件架构设计,软件架构师培训也越来越火了,,甚至也有国人自己编著软件架构设计方面的书籍 ...

  3. 理解本真的REST架构风格

    作者: 李锟  来源: InfoQ  发布时间: 2013-11-22 18:28  阅读: 23543 次  推荐: 23   原文链接   [收藏]   引子 在移动互联网.云计算迅猛发展的今天, ...

  4. 【REST系列】详解REST架构风格 —— 带你阅读Web发展史上的一个重要技术文献

    文章目录 REST详解 词组解释 论文摘要 REST架构约束 一.Client–server:客户端-服务器 二.Stateless:无状态 三.Cacheability:缓存 四.⭐Uniform ...

  5. 架构风格与基于网络的软件架构设计

    原文链接 https://blog.csdn.net/on_1y/article/details/60358117 架构风格与基于网络的软件架构设计 如今许多服务都采用了 RESTful API, 而 ...

  6. 手把手教你搭建一个基于Java的分布式爬虫系统

    http://blog.51cto.com/xpleaf/2093952 1 概述 在不用爬虫框架的情况,经过多方学习,尝试实现了一个分布式爬虫系统,并且可以将数据保存到不同地方,类似MySQL.HB ...

  7. 软件架构 - 架构风格总结

    一.软件架构概念 1. 软件架构建模 结构模型:以架构的构件.连接件和其他概念来刻画结构 框架模型:不太侧重描述结构的细节而更侧重于整体的结构 动态模型:系统的"大颗粒"的行为性质 ...

  8. 分布式爬虫系统的设计与实现(SourceForge.net数据爬取)

    目录 本科生毕业论文(设计)中文摘要 I 本科生毕业论文(设计)英文摘要 II 目录 I 图目录 III 表目录 IV 第一章 引言 1 1.1 研究背景 1 1.1.1 SourceForge.ne ...

  9. 赫拉(hera)分布式任务调度系统之项目启动(二)

    文章目录 赫拉 创建表 打包部署 测试 TIPS 加入群聊 赫拉 大数据平台,随着业务发展,每天承载着成千上万的ETL任务调度,这些任务集中在hive,shell脚本调度.怎么样让大量的ETL任务准确 ...

最新文章

  1. java.lang.NoClassDefFoundError Adding a jar to an RCP application
  2. stm32f401 i2s 时序图
  3. Vue+Openlayers+el-checkbox实现多选配置图层的显示和隐藏
  4. 【Spring】Spring第三天 - 声明式事务、常用注解、Ajax 复习
  5. kotlin函数式编程_我最喜欢的Kotlin函数式编程示例
  6. java工程窗口程序_java工程开发之图形化界面之(第二课)
  7. 关于通过ServletContext获取数据出现的http500的错误的解决方案
  8. 给mac配置adb 路径
  9. 贪心算法哈夫曼java_贪心算法_哈夫曼编码问题(Huffman Coding)
  10. 网易邮箱大师代收gmail
  11. 过来人的经验:给Java初学者的10个学习经验
  12. StringBuffer去掉最后一个字符
  13. worldpress php7.2,centos7.4下word press环境由php5.6.4升级到php7.2
  14. 华为天才少年:武大94年博士!江山代有才人出,不拘一格降人才!
  15. python selenium爬取去哪儿网的酒店信息——详细步骤及代码实现
  16. 【笨木头Unity】入门之旅010(完结):Demo之四处找死(五)_UI
  17. 营销活动的业绩,在开始之前你就应该预见到了…
  18. 周金瑞10.31现货黄金、白银TD、美原油开盘操作建议
  19. JavaScript判断对象中每一项属性都不为空
  20. python画樱桃小丸子_学python画图最快的方式——turtle小海龟画图

热门文章

  1. 酒店无线认证解决方案
  2. 六月回顾 | 盛夏已至,不负每一次期待
  3. 时序数据到底是什么,为什么我们需要时序数据库?
  4. SourceInsight 软件乱码问题
  5. PS查看设计图中文字大小,颜色
  6. 抖音广告多少种,这些你知道吗?
  7. 已知两角及其夹边,解三角形
  8. macbook 如何在开盖的情况下连接外接显示器, 同时 macbook 的键盘和触摸板都能工作
  9. 【从饮水机到名人堂之c语言】日常学习总结
  10. C语言零基础入门之“hello world“