写点什么

架构之:REST 和 RESTful

发布于: 2 小时前

简介

近几年微服务是如火如荼的在发展,而微服务之间的调用和渐渐的从 RPC 调用转移到了 HTTP 调用。于是经常听到有些同事说我们提供微服务并且暴露 RESTful 接口给别的系统,但是什么是 RESTful 接口呢?它和 REST 有什么关系呢?别急,本文将会带你一探究竟。

REST

REST 是一种架构。

首先我们要记住的是 REST 是一种架构方式,并不是一种协议。它只是告诉我们应该如何去搭建一个可靠的系统。

REST 的全称是 REpresentational State Transfer。中文可能不好翻译,我们暂将其定义为有代表性的状态转义。它是分布式系统的一种架构方式。最先是由 Roy Fielding 在 2000 年他的博士毕业论文中首先提到的。

REST 架构在现在的 web 应用中非常常见,它并不涉及到具体的编码,它只是一种高级比的指导方案,具体的实现还是由你自己决定。

REST 和 RESTful API

我们刚刚讲解了 REST,那么 REST 和 RESTful API 有什么关系呢?

我们知道,API 是服务和服务之间,客户端和服务端之间沟通的桥梁,通过 API 之间的调用,我们可以从服务器中获取到需要的资源信息。而 RESTful API 就是符合 REST 架构的 API。

所以不是所有的 HTTP 协议的 API 都是 RESTful API,它的前提是你的系统是 REST 架构的。

REST 架构的基本原则

那么什么样的系统才能被称为是 REST 架构的系统呢?根据 Roy Fielding 的论文描述,REST 架构的系统有 6 个基本特征。我们一一来说明。

Uniform interface 统一的接口

在 REST 架构中,最为核心的元素就是资源。我们将资源定义为一个个的独立的 URI。一个资源用一个独立并且唯一的 URI 来表示。

单个的资源不能太大也不能太小,它表示的是一个独立的可以操作的单位。这些资源通过通用的获取方式来进行获取和操作。比如对资源的 CURD 可以分别用不同的 HTTP method 来表示(PUT,POST,GET,DELETE)。

同时需要对资源进行统一的命名,定义统一的 link 格式和数据格式。

还有一点,根据 HATEOAS 协议,一个资源还应该包含指向该资源或者相关资源的 URI。可以能有些同学现在对这一点还有些疑惑,不过没关系,后面我们会详细对 HATEOAS 进行讲解。

Spring 也提供了对 HATEOAS 的支持,我们看一个基本的 HATEOAS 的请求:

GET http://localhost:8080/greeting

该请求的返回可以是这样的:

{  "content":"Hello, World!",  "_links":{    "self":{      "href":"http://localhost:8080/greeting?name=World"    }  }}

复制代码

大家可以看到上面返回了一个代表自己 URI 的资源链接。

Client–server 客户端和服务器端独立

另外的一条规则就是客户端和服务器端独立,客户端和服务器端互不影响,他们之间的唯一交互就是 API 的调用。

对于客户端来说只要能够通过 API 获取到对应的资源即可,并不关心服务器是怎么实现的。

而对于服务器端来说,只需要提供保持不变的 API 即可,自己内部的实现可以自由决定,也不需要考虑客户端是如何使用这些 API 的。

这条规则对于现在的很多前后端分离的架构来说已经使用了。

Stateless 无状态

和 HTTP 协议一样,REST 架构中各个服务之间的 API 调用也是无状态的。无状态的意思是服务器并不保存 API 调用的历史记录,也不存储任何关于客户端的信息。对于服务器来说,每个请求都是最新的。

所以用户的状态信息是在客户端进行保存和维护的,客户端需要在每个接口带上可以识别用户的唯一标记,从而在服务器端进行认证和识别,从而获取到对应的资源。

Cacheable 可缓存

缓存是提升系统速度的利器,对于 REST 的资源也是一样的,在 REST 中对于可缓存的资源需要标明它是可以被缓存的。

从而对应的调用方可以将这些资源进行缓存,从而提升系统的效率。

Layered system 分层系统

现代的系统基本上都是分层的,在 REST 架构中也是一样,只要保证对外提供的资源 URI 是一致的,架构并不关心你到底使用的是几层架构。

Code on demand 按需编码

一般来说,REST 架构中各个服务通常是通过 JSON 或者 XML 来进行交互的。但是这并不是硬性规定。可以返回可执行的代码直接运行。

RESTful API 的例子

我们来举几个常见的 RESTful API 的例子,来见识一下这种架构的神奇之处:

请求一个 entity:

GET https://services.odata.org/TripPinRESTierService/People

根据 ID 请求一个 entity:

GET https://services.odata.org/TripPinRESTierService/People('russellwhyte')

请求一个 entity 的某个属性:

GET https://services.odata.org/TripPinRESTierService/Airports('KSFO')/Name

使用 filter 进行查询:

GET https://services.odata.org/TripPinRESTierService/People?$filter=FirstName eq 'Scott'

修改数据:

POST https://services.odata.org/TripPinRESTierService/Peopleheader:{    Content-Type: application/json}body:{    "UserName":"lewisblack",    "FirstName":"Lewis",    "LastName":"Black",    "Emails":[        "lewisblack@example.com"    ],    "AddressInfo": [    {      "Address": "187 Suffolk Ln.",      "City": {        "Name": "Boise",        "CountryRegion": "United States",        "Region": "ID"      }    }    ]}

复制代码

删除数据:

DELETE https://services.odata.org/TripPinRESTierService/People('russellwhyte')

更新数据:

PATCH https://services.odata.org/TripPinRESTierService/People('russellwhyte')header:{    Content-Type: application/json}body:{    "FirstName": "Mirs",    "LastName": "King"}
复制代码

总结

本文讲解了 REST 和 RESTful 相关的概念,那么对于其中最重要的资源如何定义呢?敬请期待后续文章。

本文已收录于 http://www.flydean.com/01-rest-restful/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

发布于: 2 小时前阅读数: 2
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
架构之:REST和RESTful