Restful学习笔记

标签: http restful ROA 软件架构 rest
23人阅读 评论(0) 收藏 举报
分类:

关于restful的文章,网上文章搞得我云里雾里,花了点时间整理了一下,恰好最近好像很多同学跳槽,以备不时之需,毕竟谁还不是面向离职编程(:

rest, restful,restful-api

rest, restful, restful, restful-api这几个词经常在各种博客里面出现.具体什么关系呢?这个要从软件架构设计风格说起。

SOA(Service-oriented architecture): 软件的主要元素是服务。

ROA(Resource-oriented architecture): 软件的主要元素是资源。

这其实有点像面向过程编程和面向对象编程的区别。SOA视角中,软件就是由各种松耦合的服务组成的,一切都可以服务化。而在ROA视角中,软件是由资源组成的,一切软件都可以通过对资源的操作(CRUD)来完成。

Rest(Resource Representational State Transfer ): ROA的实现有很多种。具体怎么来实现以资源为中心的软件架构? 基于ROA架构风格,在Http协议定义约束下,就是REST架构风格。满足这些约束条件和原则的应用程序就是RESTful 服务,引用一下wikipedia上的一段话。

REST, describes a series of architectural constraints that exemplify how the web's design emerged (ROA).

Representational State Transfer (REST) is an architectural style that defines a set of constraints and properties based on HTTP. Web Services that conform to the REST architectural style, or RESTful web services, provide interoperability between computer systems on the Internet.

好像还是不太理解对资源的操作和服务化的区别。举个例子就好了:

假如你维护一个广告系统,要对一个广告主的账户余额进行更改。

基于服务我们会这么考虑问题:

  1. 账户相关的模块服务化,提供一个接口出来.
  2. 相关逻辑.
  3. 写相关逻辑的时候需要check这个账户是不是合法账户,需要登录验证等操作
  4. 这些内部操作最后对调用方透明的,只需要给出一个updateBilling()的接口.

基于资源我们会这么考虑问题:

  1. 对账户是不是合法我们可以用GET来对账户资源实现.
  2. 验证操作我们可以用GET来对账户信息资源实现.
  3. 更新账户余额我们可以用POST来对账户余额资源实现.

所以,我开头才会说这有点像面向过程和面向对象的区别。写逻辑不就是面向过程么,以资源为视角不就是面向对象么。

restful约束/优点

前面说restful系统遵循一定的约束,具体有哪些约束呢?满足如下6条的约束就可以被称作rest风格的架构,下面摘自维基百科。

1.客户端-服务器结构。通过一个统一的接口来分开客户端和服务器,使得两者可以独立开发和演化。客户端的实现可以简化,而服务器可以更容易的满足可伸缩性的要求。

2.无状态。在不同的客户端请求之间,服务器并不保存客户端相关的上下文状态信息。任何客户端发出的每个请求都包含了服务器处理该请求所需的全部信息。

3.可缓存。客户端可以缓存服务器返回的响应结果。服务器可以定义响应结果的缓存设置。

4.分层的系统。在分层的系统中,可能有中间服务器来处理安全策略和缓存等相关问题,以提高系统的可伸缩性。客户端并不需要了解中间的这些层次的细节。

5.按需代码(可选)。服务器可以通过传输可执行代码的方式来扩展或自定义客户端的行为。这是一个可选的约束。

6.统一接口。该约束是 REST 服务的基础,是客户端和服务器之间的桥梁。该约束又包含下面 4 个子约束。

  • 资源标识符。每个资源都有各自的标识符。客户端在请求时需要指定该标识符。在 REST 服务中,该标识符通常是 URI。
  • 通过资源的表达来操纵资源。客户端根据所得到的资源的表达中包含的信息来了解如何操纵资源,比如对资源进行修改或删除。
  • 自描述的消息。每条消息都包含足够的信息来描述如何处理该消息。
  • 超媒体作为应用状态的引擎(HATEOAS)。客户端通过服务器提供的超媒体内容中动态提供的动作来进行状态转换。

解释一下啥是HATEOASHypermedia As The Engine Of Application State)。客户端与服务器的交互完全由超媒体动态提供,客户端无需事先了解如何与数据或者服务器交互,所有的客户端后续行为完全由服务端的返回决定。相反,如果是SOA风格需要定义IDL。举例:

如下获取账户资源的请求,需要返回用XML格式表示。

GET /account/12345 HTTP/1.1
Host: bank.example.com
Accept: application/xml
...

返回结果如下:

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: ...

<?xml version="1.0"?>
<account>
    <account_number>12345</account_number>
    <balance currency="usd">100.00</balance>
    <link rel="deposit" href="https://bank.example.com/accounts/12345?deposit=12345" />
    <link rel="withdraw" href="https://bank.example.com/accounts/12345?withdraw=12345" /> 
    <link rel="transfer" href="https://bank.example.com/accounts/12345?transfer=2345" />
    <link rel="close" href="https://bank.example.com/accounts/12345?status=close" />
</account>

表示现在可以执行:存款、提款、转账、销户的操作,这些操作放在了link中。

假如账户余额不足,返回结果会是:

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Length: ...

<?xml version="1.0"?>
<account>
    <account_number>12345</account_number>
    <balance currency="usd">-25.00</balance>
    <link rel="deposit" href="https://bank.example.com/account/12345?deposit=12345" />
</account>

这样link中的结果可执行的操作只有存款这一种, 其他的链接是不可用的,所以称之为:应用状态引擎(Engine Of Application State)。客户端可能的状态依赖于资源的状态,客户端无需知道每种描述信息和交互机制,如果需要解析新的信息格式,可以依赖于第五点:按需定制代码。

最大的特点是落到基于资源、接口统一上。把所有东西抽象成资源,把操作协议统一了,系统之间的配合就有了一定的约束,将减小服务对接(撕逼)成本,这是Self-descriptive messages的基础, cache的基础。至于分层啥的,我觉得这不是每种架构风格的标配么。

REST vs SOA

REST-service

  • 网络上的资源都被抽象为资源,这些资源都具有唯一的统一资源标识符(URI:Uniform Resource Identiter)
  • 通过HTTP协议的标准动作(Get、Put、Post、Delete)通过统一的接口对资源进行操作
  • 无状态
  • 基于HTTP
  • 可以描述信息,比如信息是XML、zip、json、pdf

SOA-service

  • 通过网络终结点对外提供服务。
  • 通过调用服务接口实现软件
  • 可以有状态
  • 可以基于多种协议
  • 信息需要依赖于接口对接双方约定.

restful-api设计

这里推荐一下:阮一峰的博客,毕竟我没有在大型复杂项目中实践过。不过文中说把版本号放url中,另一篇博客理解RESTful架构又说最好版本号不要放在url中,应该是错误吧,知道的同学回答下。

相关资料


作者简介:

毕业于哈尔滨工业大学,就职小米科技,负责小米广告在线引擎的研发。

更多后端知识,请关注知乎专栏:春风得意码蹄疾

查看评论

Spring REST Controller,在GET方式下,有多个参数时的处理

现在越来越多的服务都转向使用RESTful了,我们的项目也不例外,使用spring来做了REST。在采用RESTful的时候,我们会严格按照约定来使用 HTTP METHOD: GET: 查询 PO...
  • rainbow702
  • rainbow702
  • 2016-12-20 20:30:37
  • 11497

Restful接口传入多参数的问题和解决方案

结论: restful风格的接口不支持多个参数 注:本文指的是通过json序列化参数的情况前置 解决方法: 1.封装对象 2.使用@PathVariable 3.改变序列化格式,不使用json,...
  • aitcax
  • aitcax
  • 2016-11-09 11:10:26
  • 20346

Restful Web Api Get 和 Post 请求的参数设置

1、Get请求(用HttpClient或HttpWebRequest) [HttpGet] public int Get(int id) { ...
  • zhulongxi
  • zhulongxi
  • 2016-11-05 17:23:56
  • 7816

设计一个良好的restful风格API

阅读原文版本号在 RESTful API 中,API 接口应该尽量兼容之前的版本。但是,在实际业务开发场景中,可能随着业务需求的不断迭代,现有的 API 接口无法支持旧版本的适配,此时如果强制升级服务...
  • shog808
  • shog808
  • 2018-04-13 18:29:01
  • 18

golang判断key是否在map中

判断方法示例代码 if _, ok := map[key]; ok { } 另外golang也没有提供item是否在array当中的判断方法,如果程序里面频繁用到了这种判断,可以将array转化为以...
  • xielingyun
  • xielingyun
  • 2015-11-23 15:59:08
  • 21745

对于restful如何获取前台的参数

1:查询参数?和&amp;amp;例如:一个获取用户列表的Api Urlvar url = AppContextPath + &quot;/rest/users?page=&quot;+page+&q...
  • wanghang88
  • wanghang88
  • 2016-11-04 14:11:32
  • 2822

OkHttpClient带多个参数的get请求

token放在Header里面,通过addHeader方法添加,其他的参数全部拼接在URL里面,get的多个参数放在URL后面就行了,post的多个参数需要放在RequestBody里面String ...
  • sw_gegewu
  • sw_gegewu
  • 2017-02-20 16:17:48
  • 3193

一个REST获取天气预报的客户端小例子(分别用C#和jQuery实现)

  • 2014年06月16日 16:04
  • 42KB
  • 下载

Web Service笔记(五):CXF开发RESTful风格的Web Service

1、CXF结合spring来开发RESTful风格的web servie。 2、利用jsxb映射javabean与xml 3、详解java_rs规范下的注解包...
  • u012228718
  • u012228718
  • 2014-11-26 21:30:35
  • 3233

restful里的resource类里的各种接收参数方式

一开始用的是@QueryParam来接收参数,后来学习中发现有@PathParam也可以接收,但是用法不一样,摆渡后,自己在这里做了总结: 一、@PathParam (@PathParam ,url...
  • u011038738
  • u011038738
  • 2018-01-22 11:29:48
  • 95
    个人资料
    等级:
    访问量: 7万+
    积分: 1876
    排名: 2万+
    推荐网址
    博客专栏