应用之间的通信可使用Web Services,也可使用REST(表述性状态转移),后者由于轻量级和优雅而颇受欢迎,REST基于Http,实际上就是一套对HTTP/URI的最佳实践套路。在设计应用时能坚持REST原则,那就预示着你将会获得一个使用了优质架构的系统。git
使用REST,套路分解为五条原则:github
为资源定义IDjson
充分使用ID来作连接浏览器
使用标准动词缓存
资源能够有多重表达形式安全
无状态服务器
从需求文本中提取名词和动词是一条设计的捷径。好比在电子商务应用中的一段需求描述:“客户能够点击列表内的订单,查询得到此订单”。那么订单(order)就是一个名词。定义ID也就是让每一个订单能够有一个ID来标识它。使用REST,标识的方式是这样的:架构
http://example.com/order/1 http://example.com/order/2
分别代表查询1号订单、2号订单。相似的,对于客户、商品,能够如此表达:app
http://example.com/customer/1234 http://example.com/product/4554
哦我去,那不是等于这玩意吗:curl
class OrderManager{ Order get(id:integer); } OrderManager.get(1)
并且前面还多了一个方案(http://)和主机(example.com) ,好啰嗦。然而,好处就体如今这个啰嗦里面了:
利用已被定义,现成的方案,易于理解的规则。
在全球范围中一直在运行的。你的订单能够来自example.com,或者其余叫作foo.com,bar.com之类的镜像站上,它们可能分布到全球各地。
利用现有的工具。好比订单的连接能够被多种渠道分享到朋友那里,或者加入到浏览器的书签中
处理单数名词外,还有复数的,就是一组资源,相似这样的:
http://example.com/orders/2007/11 http://example.com/products?color=green
对一类事物集合的标识。
连接是咱们在HTML中常见的概念,但还能够更加通用。以下XML片断把对应order的product和customer连接进来:
<order self="http://example.com/customers/1234"> <amount>23</amount> <product ref="http://example.com/products/4554"> <customer ref="http://example.com/customers/1234"> </customer> </product> </order>
应用程序能够由此XML“跟随”连接检索product和customer的更多数据。
还能够经过连接加入对资源的动做。好比你的帐户还有100美圆的状况下,你能够作存款取款转帐四个操做:
GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK <?xml version="1.0"?> <account> <account_number>12345</account_number> <balance currency="usd">100.00</balance> <link rel="deposit" href="/account/12345/deposit" /> <link rel="withdraw" href="/account/12345/withdraw" /> <link rel="transfer" href="/account/12345/transfer" /> </account>
要是你的帐户已经赤字,你能够作的动做就只有存款了:
GET /account/12345 HTTP/1.1 HTTP/1.1 200 OK <?xml version="1.0"?> <account> <account_number>12345</account_number> <balance currency="usd">-25.00</balance> <link rel="deposit" href="/account/12345/deposit" /> </account>
这个动做清单是和状态有关的,术语叫作HATEOAS (Hypertext As The Engine Of Application State) 。
咱们已经提过,”从需求文本中提取名词和动词”,名词说了,就是资源的命名。动词呢。好比对订单的“查询”就是动词。
http://example.com/order/1
在REST内默认就是GET,也就是“查询”。使用浏览器的场合,上面的URI在发给服务器时,会被翻译为
GET http://example.com/order/1
语义上来讲,就是查询在example.com上的ID为1的订单,使用http协议。当使用这套,在服务器放准守REST的话,你还能够获得额外的好处,就是:
幂等。若是你发送了一个GET请求没有获得结果,你可能不知道缘由是请求未能到达目的地,仍是响应在反馈的途中丢失了。幂等性保证了你能够简单地再发送一次请求解决问题。
缓存。因此在不少状况下,你甚至不须要向服务器发送请求。
GET在HTTP中被叫作动词(verb),除了GET,还有POST以外,还有PUT、DELETE、HEAD和OPTIONS。做为OO开发者的话,就能够想象到RESTful HTTP方案中的全部资源都继承自相似于这样的一个类:
class Resource { Resource(URI u); Response get(); Response post(Request r); Response put(Request r); Response delete(); }
幂等性一样适用于:
PUT。语义为:更新资源数据,若是资源不存在的话,则根据此URI建立一个新的资源
DELETE。语义为:删除一个资源,或者删除不存在的东西没有任何问题
POST方法,一般表示“建立一个新资源”,也能被用于调用任意过程,于是它既不安全也不具备幂等性。
为何使用标准方法如此重要?从根本上说,它使你的应用成为Web的一部分,统一接口也使得全部理解HTTP应用协议的组件能与你的应用交互。通用客户程序(generic client)就是从中受益的组件的例子,例如curl、wget、代理、缓存、HTTP服务器、网关还有Google、Yahoo!、MSN等等。
REST要求状态要么被放入资源状态中,要么保存在客户端上。或者换句话说,服务器端不能保持除了单次请求以外的,任何与其通讯的客户端的通讯状态。
这样作的最直接的理由就是可伸缩性—— 若是服务器须要保持客户端状态,那么大量的客户端交互会严重影响服务器的内存可用空间(footprint)。
一样一个order资源,可能响应检索的格式是xml,为了轻量级的支持移动app,如今须要支持json。这样的资源表达方式变化能够直接利用HTTP内容协商(content negotiation),而无需本身定义参数。好比原本的请求包:
GET /order/1 HTTP/1.1 Host: example.com Accept: application/vnd.mycompany.order+xml
如今可让移动客户端发出:
GET /order/1 HTTP/1.1 Host: example.com Accept: application/vnd.mycompany.order+json
返回的响应包内,能够在其HTTP Content-type头中包含着数据类型。
才有已有标准的好处是客户端和服务器均可以更好的达到互换:
若是客户程序对HTTP应用协议和一组数据格式都有所“了解”,那么它就能够用一种有意义的方式与世界上任意一个RESTful HTTP应用交互。
假若从客户端传来的数据符合应用协议,那么服务器端就可使用特定的格式处理数据,而不去关心客户端的类型
原文: https://www.infoq.com/article...
改编自: http://www.infoq.com/cn/artic...
demo code : https://github.com/1000copy/s...