《星巴克REST案例分析》由会员分享,可在线阅读,更多相关《星巴克REST案例分析(21页珍藏版)》请在金锄头文库上搜索。
1、如何获取(GET) 一杯咖啡星巴克REST案例分析我们已习惯于在大型中间件平台(比如那些实现CORBA、Web服务协议栈和J2EE的平台)之上构建分布 式系统了。在这篇文章里,我们将采取另一种做法:我们把支撑Web运行的协议和文档格式视为一种应 用平台,一种可通过轻量级中间件访问的平台。我们通过一个简单的客户服务交互的例子,展示了 Web在 应用集成中的作用。在这篇文章里,我们以Web为主要设计理念,提炼并分享了我们下本书GET/connected -Web-based integration(暂定名称)里的一些想法。引言我们知道,集成领域是不断变化的。Web的影响以及敏捷实践的潮流正在挑战我
2、们的关于“良 好的集成由什么构成”的观念。集成(integration)并不是一种夹在系统之间的专业活动; 与此相反,现在,集成是成功方案里的不可缺少的一部分。然而,仍有许多人误解并低估Web在企业计算中的作用。即便是那些精通Web的人士,也常 常要花费很大力气才能懂得,Web不是关于支持XML over HTTP的中间件方案,也不是一种 简易的RPC机制。这是相当遗憾的,因为Web不是仅能提供简单的点对点连接,它还有更大 的用处;它实际上是一个健壮的集成平台。在这篇文章里,我们将展示Web的一些值得关注的用途,我们将视之为一种可塑的、健壮的 平台,它能够对企业系统做很“酷”的事。另外,工作流
3、是企业软件最具代表性的特征。为什么要工作流?工作流(workflows)是企业计算的主要特征,它们基本上都是用中间件实现的(至少在计算 方面)。工作流把一项工作(work)划分为多个离散的步骤(steps)以及触发步骤转移的 事件(events)。工作流所实现的整个业务流程常常跨越若干企业信息系统,这给工作流带 来很多集成问题。星巴克:统一标准的咖啡需要统一标准的集成Web若要成为可用于企业集成的技术,它就必须支持工作流从而可靠地协调不同系统问 的交互,以实现更大的业务能力。要恰如其份地介绍工作流,就免不了讲述一大堆跟领域相关的技术细节,而这不是本文的主 旨,因此,我们选择了 Gregor H
4、ohpe的星巴克工作流这个比较好理解的例子来举例说明基于 Web的集成的工作原理。在这篇受到大家欢迎的博客文章里,Gregor讲述了星巴克是如何形 成-一个解耦合的(decoupled)盈利生产线的:“跟大部分餐饮企业-样,星巴克也主要致力于将订单处理的吞吐量最大化。顾客订单越多, 收入就越多。为此,他们采取了异步处理的办法。你在点单时,收银员取出一只咖啡杯,在 上面作上记号表明你点的是什么,然后把这个杯子放到队列里去。这里的队列指的是在咖啡 机前排成一列的咖啡杯。正是这个队列将收银员与咖啡师解耦开,从而,即便在咖啡师一时 忙不过来的时候,收银员仍然可以为顾客点单。他们可以在繁忙时段安排多个咖
5、啡师,就像 竞争消 费者模式(Competing Consumer)里那样。”Gregor是采用EAT技术(如面向消息的中间件)来讲解星巴克案例的,而我们将采用Web资 源(支持统一接口的可寻址实体)来讲解同一案例。实际上,我们将展示Web技术何以能够 具有跟传统EAI工具一样的可靠性,以及何以不仅仅是请求/响应协议之上的XML消息传递!首先,我们很抱歉擅自设想了星巴克的工作流程,因为我们的目的并不是精确无误地描述星 巴克,而是用基于Web的服务来讲解工作流。好的,既然讲清楚了这一点,那么我们现在开 始吧。简明陈述因为我们在讲工作流,所以我们有必要理解构成工作流的状态(states)以及将工作
6、流从一 个状态转移到另一个状态的事件(events) 我们的例子里有两个工作流,我们把它们用状 态机(state machines)表达出来了。这两个工作流是并行执行的。一个反映了顾客与星巴 克服务之间的交互(如图1),另一个刻画了由咖啡师执行的一系列动作(如 图2) o在顾客工作流里,顾客为了得到某种口味的咖啡而与星巴克服务进行交互。我们假定该工作 流里包含以下动作:顾客点单,付款,然后等待饮品。在点单与付款之间,顾客通常可以修 改菜单,比方说请求改用半脱脂牛奶。/pDrink图1顾客状态机尽管顾客看不见咖啡师,但咖啡师也有自己的状态机;这个状态机是服务实现私有的。如图 2所示,咖啡师在周而
7、复始地等待下一个订单,制作饮品,然后收取费用。当一个订单被加 入到咖啡师的队列中时,一次循环实例就开始了。*咖啡师完成订单并把饮品交付给顾客时, 工作流就结束了。EndShiftLookup Noxt Order图2蜘啡师的状态机尽管这些看似跟基于Web的集成毫不相干,但这两个状态机里的每一个状态迁移,都代表着 与Web资源的一次交互。每一次迁移,就是通过URT对资源实施HTTP操作,从而导致状态的 改变。GET和HEAD属于特例,因为它们不引起状态迁移。它们的作用是用于查看资源的当前状态。我们节奏稍快了点。理解状态机和Web,不是那么容易一口吃个胖子的。所以,让我们在Web 的背景下,来从头
8、回顾一下整个场景,逐步慢慢深入。顾客视角我们将从一张简单的故事卡片开始,它启动整个流程:Story :y I 加洲”a co什四M a customer J枇so 倾 Starbucks caEP这个故事里涉及一些有用的角色与实体。首先,里面有“顾客(Customer) ”角色。显然, 它是(隐含的)星巴克服务(Starbucks Service)的消费者。其次,里面有两个重要的实体(“咖啡”和“订单”),以及一个重要的交互(“点单”)我们的工作流正是由它启 动的。要把订单提交给星巴克,我们只要把订单的表示(representation) POST给下面这个众所周 知的星巴克点单 URI 即可
9、:http:/starbucks, example. org/orderoOrder图3点一杯咖啡图3显示了向星巴克点单的交互过程。星巴克采用自己的XML格式来表达有关实体;需要关 注的是,这个格式允许客户往里嵌入信息,以便进行点单稍后我们会看到。实际提交的 数据如图4所示。在面向人类的Web (human Web)上,消费者和服务使用HTML作为表示格式(representation format)。HTML有自己特定的语义,所有浏览器都理解并接受这些语义,比如:代表“一个 链接到其他文档或本文档内部某个书签的锚(anchor) ”。消费者应用浏览器只是 呈现HTML,状态机(也就是你!)用
10、GET和POST跟随链接。对于基于Web的集成也一样, 只不过服务和消费者不仅要就交互协议达成一致,还要就表示的格式与语义统一意见。POST /order HTTP 1.1Host: starbucks.example.orgContent-Type: application/xmlContent-Length:.latte图4 POST饮品订单星巴克服务创建一个订单资源,然后把这个新资源的位置放在HTTP报头Location里返回给 消费者。为方便起见,服务还要把这个新创建的订单资源的表示(representation)也放在 响应里。发给消费者的响应如下所示。201 CreatedLoca
11、tion: http:/starbucks.example.org/order/1234 Content-Type: application/xmlContent-Length: .latte3.00图5创建好了订单,等待付款201 Created状态表明星巳克己经成功接受了订单。Location报头给出了新创建订单的URT。 响应主体里的表示(representation)包含了所点饮品及其价格。另外,这个表示里还包含 另一个资源的URI星巴克希望我们与这个URI交互,以完成顾客工作流;我们稍后将用 到它。注意,该URI是放在标签、而不是标签里的。这里的在顾客工作流里是具有特定含义的,其 语
12、义是事先定义好的。我们巳经知道201 Created状态代码表示“成功创建资源”的意思。对于这个例子以及一般 的基于Web的集成,我们还需要其他一些有用的代码:200 0K它的意思是:一切正常;继续执行。201 Created我们刚刚创建了一个资源,一切正常。202 Accepted服务已经接受了我们的请求,并请我们对Location响应报头里的URI进行 轮询(pol 1)。这在异步处理中相当有用。303 See Other我们需要跟另一个资源交互,应该不会出错。400 Bad Request我们的请求格式有问题,应重新格式化后再提交。404 Not Found服务因为偷懒(或者保密)没有告
13、知请求失败的真实原因,但不管什么原 因,我们都得应付它。409 Conflict服务器拒绝了我们更新资源状态的请求。我们需要获取资源的当前状态(要 么检查响应实体主体,要么做-次GET操作),然后再作打算。412 Precondition Failed请求未被处理,因为 Etag、If-Match 或类似的“哨兵(guard)”报头的值不满足条件。我们需要考虑下一步怎么走。417 Expectation Failed幸亏核查一下,服务器不将接受你的请求,所以别真正发送那 个请求。500 Internal Server Error最偷懒的响应。服务器出错了,而且什么原因都没说。祝你不要碰见它。更
14、新订单星巴克很不错的一点就是,你可以按无数种不同的方式来定制自己的饮品。其实,考虑到某 些高端客户极高的要求,也许让他们按化学公式来点单更好。但我们别那么贪心至少开 始的时候。我们来看另一张故事卡片:Story 2:cha胸司Y dnnK回顾图4,显然我们在那里犯了一个错误:真正爱喝咖啡的人是不喜欢往浓咖啡里放太多热 牛奶的。我们要改正那个问题。幸运地是,Web (或更确切地说,HTTP)以及我们的服务均为 这样的改变提供了支持。首先,我们要确认我们仍然可以修改订单。有时咖啡师动作很快,在我们想修改订单之前, 他们就已经把咖啡做好了于是,我们只有慢慢享用这杯热咖啡风味的牛奶了。不过,有 时咖啡师会比较慢,这样我们就可以在订单得到咖啡师处理之前修改它了。为了知道我们是 否还能修改订单,我们通过HTTP动词OPTIONS来向订单资源查询它接受哪些操作(如图6)。请求响应OPTIONS /order/1234 HTTP 1. 1 Host: starbucks.example, org200 OK Allow: GET, PUT图6看看有哪些选择(OPTIONS)从图6我们可以知道,订单资源既是可读的(支持GET)、也是可更新的(支持PUT)。作为 好网民,我