当前位置: 首页 > news >正文

REST构架风格介绍之二:CRUD

上一节我们通过两个例子初步体会了 REST 状态表述转移的味道,但应该指出这两个例子还仅仅是简单的资源获取。 REST 是以资源为核心的,没有服务的概念,这的确让人怀疑 REST 能否像 ORB SOA 一样支持复杂的应用?在回答这个问题之前,让我们先暂时离开 REST ,把眼光转向基于关系数据库的 3 层构架。

通常业务逻辑层对外提供若干的功能接口(如图中定义的IOrderService),对内通过数据访问层访问数据库。我们知道,关系数据库只定义了CRUD(Create, Read, Update, Delete)四种标准的数据操作,分别对应于insert/select/update/delete四种sql语句。经验告诉我们,关系数据库在若干张表上进行关系运算是足以支持各种复杂业务逻辑的,因为所有业务功能最终都会被映射到数据库上的CRUD四种标准操作。下面这个有趣的三角形能帮助我们理解这个问题:

图中的三角分别代表:数据类型、操作、实例。可以把他们想象成可以调节的按钮,业务逻辑层的方式是:定义了少量的服务实例,把大量的操作放在服务实例下面,形象地比喻为“一扇小门,里面装了很多东西”;而数据库的方式则是提供了大量数据实例和CRUD四种标准操作,可比喻为“很多门,每扇门里面装少量的东西”。

以资源为核心的REST和以数据为核心的关系数据库是类似的。数据和资源本质上都是状态,对状态的操作CRUD少一个不行,多一个多余。因此,REST也采用CRUD四种标准操作,分别对应于HTTP协议的POST/GET/PUT/DELETE方法。虽然HTTP协议支持POST/GET/PUT/DELETE以外的HEAD等方法,可以把这些非标准方法作为有用的补充,但不应影响REST模型的纯洁性。上一节中,我们看到REST风格的应用像一个状态机;而这里我们则看到它像一个数据库。REST方式定义出的资源(Url)和相应的操作就像下面这个样子(值得重申的是,从Url的含义“统一资源定位符”就可以看出其通用性,这也是REST资源表示的优势所在):

REST完美地结合了HTTP协议,所以更容易无缝接入互联网。另外,有人提到 “一个网站对外暴露的网页数可以作为衡量它为互联网所做贡献的指标”,如果从这个角度来看,以资源为核心的REST方式比服务为核心的SOA对互联网更加友好。但应该采用哪种风格的构架还是取决于应用本身的特点,一般来讲,对于以提供和管理数据为主的,且希望做SEO的应用适合REST风格,这包括大多数WEB2.0的应用;而以计算和业务逻辑为主,且强调安全性的应用不太适合REST风格。但应避免不加分析先入为主的采用面向服务的思维,有时候恰当运用状态表述转移模式的REST构架不但可以实现业务逻辑,而且具有更好的伸缩性,正如上一节谈到的心理测试服务和Google搜索一样。REST的价值就在于让我们在设计构架的时候多了一种视角,所谓“眼界决定世界”。

Cache

由于RESTUrl表示资源和无状态服务特点,使得Cache机制变得异常简单,且HTTP协议中有直接支持。服务器响应可以通过cache-control:max-age,expires指定资源缓存时间;还可以在响应头的last-modified参数标明资源的最后修改时间,客户端请求可以带上if-modified-since参数,如果资源未过期,服务器只需用返回304 not modified状态即可,这样就避免了服务器端重复工作,也节省网络带宽;etag参数也是常用的cache控制参数,可以解决last-modified时间精度不够的问题。另外,HTTP协议还对Proxy机制有直接的支持,与Cache机制结合,在需要高性能的应用中,可以在服务器与客户端之间部署若干专门用于Cache目的Caching Proxy Server提高系统吞吐量

总结

最后总结一下REST的要点:1. Url表示资源;2.  CRUD操作;3. 状态表述转移。至于无状态服务、Http状态码、Cache控制、Proxy等则属于上面几个要点的推论,理解REST的关键还在于理解以资源为核心的模型。本文是我接触REST不到一年时间的一些体会和总结,深知对REST的掌握和应用还需继续努力,希望得到高手的指点!

相关链接

1.《如何获取一杯咖啡——星巴克REST案例分析》

2.《深入浅出REST》

 

相关文章:

  • Silverlight for Windows Phone 7开发系列(4):动画开发
  • BizTalk 2013 Beta 新特性介绍
  • 剖析Elasticsearch集群系列之一:Elasticsearch的存储模型和读写操作
  • 如何实现在firefox下显示手形光标
  • QTP的那些事--systemutil对象使用
  • 使用泛型解决需要动态返回类型的问题
  • 解决接收不到组播包的问题
  • Java @Override报错
  • 简单的汉化ECLIPSE的办法 [转]
  • 两个神奇的SQL语句
  • OPC客户端设计
  • 委托、Lambda表达式、事件系列07,使用EventHandler委托
  • 推荐一款 chrome SSH 插件 - Secure Shell
  • AngularJS中有关Directive的汇总
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 2017-08-04 前端日报
  • Android系统模拟器绘制实现概述
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • golang中接口赋值与方法集
  • javascript从右向左截取指定位数字符的3种方法
  • jQuery(一)
  • Python 基础起步 (十) 什么叫函数?
  • python 装饰器(一)
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • vue-router 实现分析
  • 给github项目添加CI badge
  • 关于for循环的简单归纳
  • 开源SQL-on-Hadoop系统一览
  • 力扣(LeetCode)56
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 使用agvtool更改app version/build
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 问题之ssh中Host key verification failed的解决
  • 回归生活:清理微信公众号
  • ​业务双活的数据切换思路设计(下)
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (3)nginx 配置(nginx.conf)
  • (Bean工厂的后处理器入门)学习Spring的第七天
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (七)理解angular中的module和injector,即依赖注入
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (转)Linux下编译安装log4cxx
  • (转)详解PHP处理密码的几种方式
  • .chm格式文件如何阅读
  • .NET 反射 Reflect
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .NET程序员迈向卓越的必由之路
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • @cacheable 是否缓存成功_Spring Cache缓存注解