RESTful API 设计规范

不想你离开。 提交于 2020-08-05 07:05:46

目录

REST

早古时期,软件和网络是两个不同的领域,前者围绕着单机环境展开,而后者则研究系统之间的通信。随着互联网的兴起,使得这两个领域开始融合,首当其冲的就是基于 HTTP 协议的 Web 服务,越来越多的人开始意识到,“网站” 即是 “软件”。

其中的先驱者就是 Tim Berners-Lee(万维网的发明者,万维网联盟负责人)和 Roy Thomas Fielding(1996 HTTP/1.0、1999 HTTP/1.1 的主要设计者之一,Apache 基金会的第一任主席,Apache Web Server 和 HTTP 协议是共生共荣的关系)等人。

1989年,Tim Berners-Lee 在论文中提出可以在互联网上构建超链接文档,并提出了三点基本要素:

  1. URI(Uniform Resource Identifier):统一资源标识符,是资源(Resource)在互联网中的唯一标识。
  2. HTML(Hyper Text Markup Language):超文本标记语言,超文本文档是由 HTML 标签组成的描述性文本,HTML 标签将文字,图形、动画、声音、表格、链接等内容格式进行了统一。
  3. HTTP(Hyper Text Transfer Protocol):超文本传输协议,传输超文本文档的传输协议,传输的数据主体称为 Message(消息)。

首先我们需要对 Resource 的概念有一个清晰的理解。所谓 Resource,就是互联网上的一个实体,或者叫具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体实物的抽象。在互联网中使用 URI 来唯一标记一个 Resource,包含了 URL 和 URN。

  • URL(Uniform Resource Loader):统一资源定位符,侧重于 “定位” 二字。
  • URN(Uniform Resource Name):统一资源名称,侧重于 “命名” 二字。

举个例子:寻找一个具体的人(URI)。使用地址来寻找就是 URL:XX省XX市XX区XX单元XX室的主人;使用身份证号和名字来寻找就是 URN:身份证号 + 名字(但无法确认人的地址)。两者各有场景,但需要注意的是 URL、URN 都是 URI 的子集,但日常生活中最常见的是 URL,所以大家口头上也习惯使用 URL 来说明一个 Resource。但在实际编码中,开发者仍要注意 URI 和 URL 的本质区别,注意规范选词。

在这里插入图片描述

REST(Representational State Transfer,表现层状态转移)最初被 Roy Thomas Fielding 在 2000 年的博士论文《Architectural Styles and the Design of Network-based Software Architectures(架构风格和基于网络的软件架构设计)》中提出。顾名思义,Roy Thomas Fielding 在这篇论文中主要讨论的是:如何在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。

可见,REST、HTTP 协议、Web 网站,三者之间天生联系紧密。基于此,我们要清晰理解 Representational State Transfer 含义的前提是要对 HTTP 协议有一定的认识。

Representational State Transfer 的含义:

  • Representational(表现层):即 Resources 的表现层。上述我们知道 Resource 是一种抽象,它具有多种表现形式,而最终把 Resource 具体呈现出来的形式,就叫做它的 “表现层”。例如:一个文本资源可以使用 txt 格式表现,也可以使用 HTML、XML、JSON 等格式表现。在 HTTP/1.0 中,Roy Thomas Fielding 为 HTTP Header 设计了 Content-Type 字段来描述这个 Resource 的 Representational。

所以,需要注意的是:URI 仅用于表示一个 Resource,不应该在 URI 中描述表现层的内容,一个优雅的 RESTful API 应该使用 Content-Type 字段来描述 Resource 的表现层。

  • State Transfer(状态转移):Resource 作为 C/S 交互的实体,必然存在着状态的变化,然而 HTTP 是一种无状态的协议(不传输资源状态的描述)。这意味着:Resource 的状态都保存在服务端,客户端想要操作某个 Resource(改变其状态)就必须通过某种手段让 Resource 在服务端发生状态的 “转移”,而且这种 “转移” 必然是建立在 Resource 的 “表现层” 之上的,例如:创建一个图片资源、删除一个图片资源;启动一个服务,关闭一个服务。故称之为 “表现层状态转移”。

而客户端使用的手段就是 Roy Thomas Fielding 在 HTTP 请求行中设计的 Request Methods(在 HTTP/1.0 中首次引入了 POST、Head 方法,在 HTTP/1.1 中引入了 PUT 方法)。

至此,我们回头再看,REST 讨论的其实是一个:如何将软件和网络两个领域进行交叉融合,继而得到一个功能强、性能好、适宜通信的互联网软件架构的问题。

虽然 REST 架构在今天(2020)的软件设计中随处可见,但了解其诞生的历史背景和发展历程,还是会对这些先驱者们产生由衷的敬意。

RESTful API

*-ful 在西文语境中常用于表示一种风格,RESTful API 就是符合 REST 架构设计思想的软件 API 风格。

笔者最早认识到 RESTful API,源于时任 AWS CTO 的一封内部邮件,那时是 2006 年,正值 AWS 孵化的初期,印象非常深刻的有两点:

  1. 强调 AWS 必须是一种 Resilient software architecture(具有韧性/弹性的软件架构)。
  2. 不使用 RESTful API 的员工将被辞退。

直到 2013 年笔者接触 OpenStack(OpenStack 初期常被认为是 AWS 的开源对标版本)之后才更深刻的体会到了其内涵和精髓。一言以蔽之就是:大型分布式软件的各个组件之间必须具备解耦和扩展的能力,网络(Network-base)是组件之间通信的唯一依赖,且对资源的操作具有唯一的确定性

退一步的,我们可以选取一个角度来比较一下 RESTful 与另外两种常见的分布式架构风格的区别:

  • RESTful 抽象的是资源,资源的抽象不需要依赖开发平台或编程语言,客户端和服务端完全松耦合。
  • DO(Distributed Objects,分布式对象)抽象的是对象,而不同的编程语言对对象的定义有很大差别,所以 DO 架构通常会与某种编程语言(.NET)绑定,若跨语言交互,实现则会非常复杂。架构实例有 RMI、EJB/DCOM、.NET Remoting 等。
  • RPC(Remote Procedure Call,远程过程调用)抽象的是过程,这要求客户端和服务端具有很强的耦合度,否者双方无法理解对方的意图。所以 RESTful 只需要以名词为核心的,而 RPC 则需要以动词为核心。架构实例有 SOAP、XML-RPC、Flash AMF 等。

AWS 奉行的这一铁律,使其得以在几年间飞速扩展至上百个核心组件,成为了极具韧性和良好生态的公有云架构。现在的软件公司基本都会采用 RESTful API 风格,让产品可以通过 API 的方式融入到行业生态中,形成 APIs 经济效益。

RESTful API 设计规范

coming soon…

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!