2018年1月20日星期六

五年架构师讲述 RESTful 架构风格


Linuxeden 开源社区 --

在移动互联网的大潮下,随着 docker 等技术的兴起,『微服务』的概念也越来越被大家接受并应用于实践,日益增多的 web service 逐渐统一于 RESTful 架构风格,如果开发者对 RESTful 架构风格不甚了解,则开发出的所谓 RESTful API 总会貌合神离,不够规范。

本文是我对 RESTful 架构风格的一些理解,和大家分享一下,如果有问题,欢迎讨论。

Outline

  • 1. RESTful 架构风格
  • 1.1.1 资源
  • 1.1.2 统一接口
  • 1.1.3 URI
  • 1.1.4 无状态
  • 1.1 RESTful 架构风格的特点
  • 1.2 ROA、SOA、REST 与 RPC
  • 1.3 本真 REST 与 hybrid 风格
  • 2. 认证机制
  • 2.1 Basic Auth
  • 2.2 Token Auth
  • 2.3 OAuth
  • 3. 总结

1. RESTful 架构风格

RESTful 架构风格最初由 Roy T. Fielding(HTTP/1.1 协议专家组负责人)在其 2000 年的博士学位论文中提出。HTTP 就是该架构风格的一个典型应用。从其诞生之日开始,它就因其可扩展性和简单性受到越来越多的架构师和开发者们的青睐。一方面,随着云计算和移动计算的兴起,许多企业愿意在互联网上共享自己的数据、功能;另一方面,在企业中,RESTful API(也称 RESTful Web 服务)也逐渐超越 SOAP 成为实现 SOA 的重要手段之一。时至今日,RESTful 架构风格已成为企业级服务的标配。

REST 即 Representational State Transfer 的缩写,可译为” 表现层状态转化”。REST 最大的几个特点为:资源、统一接口、URI 和无状态。

1.1 RESTful 架构风格的特点

1.1.1 资源

所谓” 资源”,就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。资源总要通过某种载体反应其内容,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式表现,甚至可以采用二进制格式;图片可以用 JPG 格式表现,也可以用 PNG 格式表现;JSON 是现在最常用的资源表示格式。

结合我的开发实践,我对资源和数据理解如下:

资源是以 json(或其他 Representation) 为载体的、面向用户的一组数据集,资源对信息的表达倾向于概念模型中的数据:

  • 资源总是以某种 Representation 为载体显示的,即序列化的信息
  • 常用的 Representation 是 json(推荐) 或者 xml(不推荐)等
  • Representation 是 REST 架构的表现层

相对而言,数据(尤其是数据库)是一种更加抽象的、对计算机更高效和友好的数据表现形式,更多的存在于逻辑模型中

资源和数据关系如下:

1.1.2 统一接口

RESTful 架构风格规定,数据的元操作,即 CRUD(create, read, update 和 delete, 即数据的增删查改) 操作,分别对应于 HTTP 方法:GET 用来获取资源,POST 用来新建资源(也可以用于更新资源),PUT 用来更新资源,DELETE 用来删除资源,这样就统一了数据操作的接口,仅通过 HTTP 方法,就可以完成对数据的所有增删查改工作。

即:

  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据)。
  • DELETE(DELETE):从服务器删除资源。

1.1.3 URI

可以用一个 URI(统一资源定位符)指向资源,即每个 URI 都对应一个特定的资源。要获取这个资源,访问它的 URI 就可以,因此 URI 就成了每一个资源的地址或识别符。

一般的,每个资源至少有一个 URI 与之对应,最典型的 URI 即 URL。

1.1.4 无状态

所谓无状态的,即所有的资源,都可以通过 URI 定位,而且这个定位与其他资源无关,也不会因为其他资源的变化而改变。有状态和无状态的区别,举个简单的例子说明一下。如查询员工的工资,如果查询工资是需要登录系统,进入查询工资的页面,执行相关操作后,获取工资的多少,则这种情况是 有状态 的,因为查询工资的每一步操作都依赖于前一步操作,只要前置操作不成功,后续操作就无法执行;如果输入一个 url 即可得到指定员工的工资,则这种情况是 无状态 的,因为获取工资不依赖于其他资源或状态,且这种情况下,员工工资是一个资源,由一个 url 与之对应,可以通过 HTTP 中的 GET 方法得到资源,这是典型的 RESTful 风格。

1.2 ROA、SOA、REST 与 RPC

ROA 即 Resource Oriented Architecture,RESTful 架构风格的服务是围绕 资源 展开的,是典型的 ROA 架构(虽然“A”和“架构”存在重复,但说无妨),虽然 ROA 与 SOA 并不冲突,甚至把 ROA 看做 SOA 的一种也未尝不可,但由于 RPC 也是 SOA,比较久远一点点论文、博客或图书也常把 SOA 与 RPC 混在一起讨论,因此,RESTful 架构风格的服务通常被称之为 ROA 架构,很少提及 SOA 架构,以便更加显式的与 RPC 区分。

RPC 风格曾是 Web Service 的主流,最初是基于 XML-RPC 协议(一个远程过程调用(remote procedure call,RPC) 的分布式计算协议),后来渐渐被 SOAP 协议(简单对象访问协议(Simple Object Access Protocol))取代;RPC 风格的服务,不仅可以用 HTTP,还可以用 TCP 或其他通信协议。但 RPC 风格的服务,受开发服务采用语言的束缚比较大,如.NET 框架中,开发 web service 的传统方式是使用 WCF,基于 WCF 开发的服务即 RPC 风格的服务,使用该服务的客户端通常要用 C#来实现,如果使用 python 或其他语言,很难实现可以直接与服务通信客户端;进入移动互联网时代后,RPC 风格的服务很难在移动终端使用,而 RESTful 风格的服务,由于可以直接以 jsonxml 为载体承载数据,以 HTTP 方法为统一接口完成数据操作,客户端的开发不依赖于服务实现的技术,移动终端也可以轻松使用服务,这也加剧了 REST 取代 RPC 成为 web service 的主导。

RPC 与 RESTful 的区别如下面两个图所示:

1.3 本真 REST 与 hybrid 风格

通常开发者做服务相关的客户端开发时,使用的所谓 RESTful 服务,基本可分为 本真 RESThybrid 风格 两类。本真 REST 即我上文阐述的 RESTful 架构风格,具有上述的 4 个特点,是真正意义上的 RESTful 风格;而 hybrid 风格 ,只是借鉴了 RESTful 的一些优点,具有一部分 RESTful 的特点,但对外依然宣称是 RESTful 风格的服务。(窃以为,正是由于 hybrid 风格服务混淆了 RESTful 的概念,才在 RESTful 架构风格提出了本真 REST 的概念,以为了划分界限 :P)

hybrid 风格的最主流的用法是,使用 GET 方法获取资源,用 POST 方法实现资源的创建、修改和删除。hybrid 风格之所以存在,据我了解有两种来源:一种情况是因为,某些开发者并没有真正理解何为 RESTful 架构风格,导致开发的服务貌合神离;而主流的原因是由于历史包袱 —— 服务本来是 RPC 风格的,由于上文提到的 RPC 的劣势及 RESTful 的优势,开发者在 RPC 风格的服务上又包装了一层 RESTful 的外壳,通常这层外壳只为获取资源服务,因此会按 RESTful 风格实现 GET 方法,如果客户端提出一些简单的创建、修改或删除数据的需求,则通过 HTTP 协议中最常用的 POST 方法实现相应功能。

因此,开发 RESTful 服务,如果没有历史包袱,不建议使用 hybrid 风格。

针对上面的技术我特意整理了一下,有很多技术不是靠几句话能讲清楚,所以干脆找朋友录制了一些视频,很多问题其实很简单,但是背后的思考和逻辑不简单,要做到知其然还要知其所以然。如果想学习 Java 工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty 源码分析的朋友可以加我的 Java 进阶群:694549689,群里有阿里大牛直播讲解技术,以及 Java 大型互联网技术的视频免费分享给大家。

精彩继续~

2. 认证机制

由于 RESTful 风格的服务是无状态的,认证机制尤为重要。例如上文提到的员工工资,这应该是一个隐私资源,只有员工本人或其他少数有权限的人有资格看到,如果不通过权限认证机制对资源做一层限制,那么所有资源都以公开方式暴露出来,这是不合理的,也是很危险的。

认证机制解决的问题是,确定访问资源的用户是谁;权限机制解决的问题是,确定用户是否被许可使用、修改、删除或创建资源。权限机制通常与服务的业务逻辑绑定,因此权限机制需要在每个系统内部定制,而认证机制基本上是通用的,常用的认证机制包括 session auth(即通过用户名密码登录),basic authtoken authOAuth,服务开发中常用的认证机制为后三者。

2.1 Basic Auth

HTTP Basic authentication (BA) implementation is the simplest technique for enforcing access controls to web resources because it doesn’t require cookies, session identifier and login pages. Rather, HTTP Basic authentication uses static, standard fields in the HTTP header which means that no handshakes have to be done in anticipation.

Visit Wikipedia To Read More

简言之,Basic Auth 是配合 RESTful API 使用的最简单的认证方式,只需提供用户名密码即可,但由于有把用户名密码暴露给第三方客户端的风险,在生产环境下被使用的越来越少。因此,在开发对外开放的 RESTful API 时,尽量避免采用 Basic Auth

2.2 Token Auth

Token Auth 并不常用,它与 Basic Auth 的区别是,不将用户名和密码发送给服务器做用户认证,而是向服务器发送一个事先在服务器端生成的 token 来做认证。因此 Token Auth 要求服务器端要具备一套完整的 Token 创建和管理机制,该机制的实现会增加大量且非必须的服务器端开发工作,也不见得这套机制足够安全和通用,因此 Token Auth 用的并不多。

本文不在展开介绍 Token Auth,我个人对这套机制也了解有限,有兴趣了解这套机制的同学不妨从 Stack Overflow 上的这篇讨论入手。

在这里给大家提供一个学习交流的平台,java 架构师群:694549689

  1. 具有 1-5 工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加群。
  2. 在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加群。
  3. 如果没有工作经验,但基础非常扎实,对 java 工作机制,常用设计思想,常用 java 开发框架掌握熟练的可以加群。

2.3 OAuth

OAuth is an open standard for authorization. OAuth provides client applications a ‘secure delegated access’ to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The client then uses the access token to access the protected resources hosted by the resource server. OAuth is commonly used as a way for Internet users to log into third party websites using their Microsoft, Google, Facebook or Twitter accounts without exposing their password.

OAuth is a service that is complementary to and distinct from OpenID. OAuth is also distinct from OATH, which is a reference architecture for authentication, not a standard for authorization. However, OAuth is directly related to OpenID Connect (OIDC) since OIDC is an authentication layer built on top of OAuth 2.0.

Visit Wikipedia To Read More

OAuth(开放授权)是一个开放的授权标准,允许用户让第三方应用访问该用户在某一 web 服务上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的第三方系统(例如,视频编辑网站) 在特定的时段(例如,接下来的 2 小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth 让用户可以授权第三方网站访问他们存储在另外服务提供者的某些特定信息,而非所有内容。

正是由于 OAUTH 的严谨性和安全性,现在 OAUTH 已成为 RESTful 架构风格中最常用的认证机制,和 RESTful 架构风格一起,成为企业级服务的标配。

目前 OAuth 已经从 OAuth1.0 发展到 OAuth2.0,但这二者并非平滑过渡升级,OAuth2.0 在保证安全性的前提下大大减少了客户端开发的复杂性,因此,Gevin 建议在实战应用中采用 OAuth2.0 认证机制。

现在网上关于 OAuth 的资料非常丰富,也有大量开源的第三方库实现了 OAuth 机制,不熟悉 OAuth 的同学从 OAuth 官网入手即可。

3. 总结

  • 本真 REST + OAuth 是 RESTful 是微服务的标配
  • Basic Auth 只在开发环境中使用
  • 设计合理的资源
  • 用正确的 HTTP 方法对数据发正确的请求

转自 http://ift.tt/2roGLHz

The post 五年架构师讲述 RESTful 架构风格 appeared first on Linuxeden开源社区.

http://ift.tt/2DU4fa0

没有评论:

发表评论