RESTful API 设计最佳实践(1)

RESTful API 设计最佳实践(1)

——在Roy Thomas Fielding看来,这可能(kending)不是真正的REST,但也将是一个因REST所带来的好的实践。

一、Representational State Transfer (REST)概述

1. 相关概念

(1)资源: rest对于资源的定义基于一个简单的前提:标识符的改变应该尽可能少的发生,将一个资源定义为创作者想要标识的语义,而不是对应于创建这些引用时的那些语义的值。因此,资源定义为一个URI标识了的概念,而不是一个标识了的文档。这是我们在定义资源时的依据,也决定我们定义的接口是否是足够通用和统一接口。REST中的资源所指的不是数据,而是数据和表现形式的组合,比如“我的粉丝”和“我关注的人”在数据上可能有重叠或者完全相同,而由于他们的表现形式不同,所以被归为不同的资源。
(2)资源的表述: 用于描述资源在某个时刻所处的状态。我们可以使用不同的格式来表述资源,如HTML/XML/JSON/纯文本/图片/视频/音频等。
(3)状态转移: 在客户端和服务器端之间转移代表资源状态的表述。如服务器将某个资源某个时刻的状态转移到客户端,客户端可以操作这些表述。
(4)统一接口: 对于基于HTTP协议实现的REST,规范的接口标准包括:使用统一的HTTP方法GET/POST/PUT/DELETE/PATCH等,使用HTTP规范的Header,状态码等。另外,在REST中,操作对于中间件事可见的,因此,操作不能隐藏于消息体中,而是要放在Header中。
(5)超文本驱动(HATEOAS): 也就是说,使用超媒体来驱动状态迁移。WEB应用可以看做一个由很多状态组成的有限状态机,客户端可以选择进入某个应用状态,使其在应用系统中前进。最常见的例子就是网页(HTML)。打开一个资源链接,服务器端以超文本的形式将当前资源状态和关联的资源(超链接)暴露出来,用户通过点击某个超链接,从当前状态迁移到下一个状态。

二、何为REST

Roy Fielding论文中,对REST风格的服务定义了6个基本约束:

  • 统一接口
  • 无状态
  • 可缓存
  • Client-Server
  • 分层系统
  • 按需代码(可选)

在他看来,如果满足不了前面5个约束,那么就不能说是真正的REST风格架构。目前来看,关于REST的很多理解都还是模糊的,难以精确判断一个架构是否是真正的REST风格架构。很多服务宣称自己是完全满足REST规范,但真正满足上述约束的可能也不多。

1. 统一接口

Roy Fielding对统一接口也提出了四个约束:

  • 基于资源
  • 通过资源表述来操作资源
  • 自描述消息
  • 以超媒体作为应用状态的驱动

因为涉及内容较多,后续会专门开两篇博客进行介绍,在此不作详述。

2. 无状态

无状态服务,是REST风格服务的核心约束。无状态指的是:处理请求所需要的状态信息都放在请求里面(如,放在URI路径、查询参数、body以及Header中等),而不是存放在服务器端。服务器端从请求中获取到相关状态信息,对请求进行处理之后,将需要返回的状态信息放在诸如body、header中,返回给客户端。无状态服务,是不要求请求有先后次序的。

关于这一约束,想介绍的东西有点多,在后面会专门开一篇博客进行讲解,这里不作详述。

3. 可缓存

在REST风格服务中,客户端可以对服务端返回的结果进行缓存。因此,服务端在响应消息中,必须通过某些方式告知客户端,该返回的消息是否可以缓存,可以缓存多久,缓存的机制是什么。通过缓存,可以提升网络效率,提升响应速度,进而提升用户体验。

4. 客户端与服务器端分离

客户端与服务器端分离,可以带来一些好处:

  • 职责明确:客户端与服务器端的分离,使得客户端不必关注与服务器端数据是怎样存储的,是通过怎样的逻辑计算出来的,它只关注与自己界面显示以及与用户交互相关的事情;而服务器端则不需要关心客户端如何与用户交互,如何展示界面,它只需要根据客户端的请求,返回其所需的数据即可。
  • 可移植性提高:在不同的平台,只需替换相应的客户端实现就可以,只要其满足同一份通信协议。
  • 水平伸缩性提高:服务器端不必关心用户状态和用户交互,因此可以实现更加精简和可水平扩展的组件,服务器端可以建立集群,客户端则无需改变。
  • 客户端与服务器端独立发展: 分离之后,客户端的发展不再受服务器的限制,而服务器的发展也不单纯只为满足某一个客户端,这也是现在互联网发展的需求。也就是说,客户端完全可以同时连多个不同服务,展现不同的界面;服务器端也可以为其他客户端提供数据;这样也提高了资源利用率。

5. 分层系统

分层系统最经典也是最常见的例子应该就是OSI七层模型了(也有将其划为5层模型)。在分层系统中,下层系统只为其上一层提供服务,不能跨层访问,也不能逆向服务。中间层的使用,可以用于提升系统的响应能力(如缓存),或者提升伸缩性(如负载平衡),亦或是安全性(如安全认证、防火墙)等。

但分层也有不好的地方,就是层次过会带来一些额外的开销和延迟,拉低系统的响应效率。但在互联网web服务中,通过适当缓存等策略,可以降低这种影响。

在传统的分层系统中,中间层很难改变传过来的消息的内容,因为中间层对传过来的消息都是不理解的,比如消息的编码格式等。但在REST架构中,中间层是有这种能力的,只要每一层的实现都满足REST的约束,那么层与层之间的消息都是自描述的,中间层也就完全有能力对其进行修改。

6. 按需代码(可选)

按需代码指的是服务器端可以将一些逻辑代码传给客户端,客户端则可以执行这些代码。这样就可以灵活地适应需求的更改,比如java applets就是这样一种方式。

三、REST 成熟度模型

Level 0 : web服务只是使用HTTP作为应用协议,实际上只是RPC的一种具体形式,SOAP和XML-RPC都属于此类。
Level 1: web服务引入了资源的概念。每个资源都有对应的标识符和表达。
Level 2: web服务使用了不同的HTTP方法来进行操作,并使用HTTP状态码表示不同结果。
Level 3: web服务使用HATEOAS(超媒体驱动),在资源表述中包含了连接信息,客户端可以根据连接来发现可以执行的动作。

目前我们所见的绝大多数的REST风格服务只是在0、1、2这几层有一定的设计。对于Level 3,下面提到的github和facebook对于分页的处理中有用到,但很难说github和facebook就做到了真正的REST服务。

四、后续

上述内容大致介绍了REST服务相关的概念,以及它的六条约束。这六个约束是判断一个架构是否是REST风格的本质要求(最后一个为可选约束)。但是,有些看似“违法”约束的设计,对于良好的REST架构没有任何影响,因此,不能一味遵循教条主义,按需设计架构,也是很重要的。在下一篇博客中,我将对比介绍REST风格架构与其他一些RPC、RMI架构各自的优劣。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值