rest

【虎.无名】从javaeye上看到三篇文章:
dlee : 主题:关于REST一些最新的业界动态 时间:2007-06-02 关键字: REST 
robbin : 主题:从分布式系统的角度看REST 时间:2007-05-23 
AllenYoung : 主题:关于REST的一点想法,欢迎大家讨论。时间:2007-04-11

1,首先,最重要的是,Sun启动了JSR 311的开发过程:http://www.infoq.com/news/2007/02/jsr-311-java-rest-api 和 JSR 311: JAX-RS: The Java API for RESTful Web Services 这个JSR的开发还请了目前最成熟的Java REST框架Restlet的作者Jerome Louvel参与到其中,Restlet API很有可能会被JCP采纳作为制定这个新标准的基础。 
孟岩前一段时间告诉我: 我刚刚从美国回来,参加了IBM Impact 07大会,现在IBM已经把REST放在SOA整个的战略框架之中来考虑,因此很快会出现商业的REST支持产品。 
M$前一段时间刚刚发布他们的REST风格的Web服务解决方案Astoria:http://www.infoq.com/cn/news/2007/05/astoria 
Nokia也将REST作为他们服务器端整体架构中的一个重要的部分:http://www.ftponline.com/conferences/virtual/wb20/2006/materials/Development/RemoteControlforWEB20.pdf 此外还有很多公司对REST感兴趣,我的一个在BO(http://www.businessobjects.com/)的朋友说他们现在做的项目已经有一半都是基于REST了,我的另一个在毕博软件的朋友说他们也对REST很感兴趣。 
O'Reilly最近出版了一本关于REST的专著:RESTful Web Services http://www.oreilly.com/catalog/9780596529260/

2,REST最大的特点是什么呢?REST是为通过HTTP协议来进行分布式调用量身定造的架构。传统上,我们开发一个非分布式的软件系统,使用OO进行建模和架构,无往而不利。但是分布式对象却显得不那么有效。对于跨进程的调用,也许我们需要探索更好的面向对象的分布式调用架构。 REST是专门为分布式调用设计的架构,在REST里面,分布式是通过对资源的操作来实现的,不是像EJB那样通过对象的方法调用来实现的。资源是一种抽象的概念,资源被映射到相应的一套URL规则上面了。所以资源只和URL相关,而与具体实现无关,因此REST具有更好的解藕性。在RoR的实现当中,你可以把一些资源直接映射到model对象上面去,也可以不映射到model上面,而完全是由业务逻辑组合的抽象资源。

3,REST提出了一些设计概念和准则:

  1. 网络上的所有事物都被抽象为资源(resource);【REST通过URI暴露资源,而不是通过消息接口暴露服务】
  2. 每个资源对应一个唯一的资源标识(resource identifier); 【虎.无名:id不一定是数字,也可是任意字符串,包括中文。完整的资源id实质是一个URI】
  3. 通过通用的连接器接口(generic connector interface)对资源进行操作;【虎.无名:会HTTP就行】
  4. 对资源的各种操作不会改变资源标识; 【虎.无名:URL的一致性,便于搜索引擎优化。SEO】
  5. 所有的操作都是无状态的(stateless)。 【虎.无名:这点比较难,很多地方需要重构,尤其设计用户登录、权限、会话等部分,要求通过其它方式,每次访问都含有有效登录信息,自动登录。】

REST之所以能够简化开发,是因为其引入的架构约束,比如Rails 1.2中对REST的实现默认把controller中的方法限制在7个:index、show、new、edit、create、update和destory,这实际上就是对CURD的实现。更进一步讲,Rails(也是当今大部分网络应用)使用HTTP作为generic connector interface,HTTP则把对一个url的操作限制在了4个之内:GET、POST、PUT和DELETE。
REST之所以能够提高系统的可伸缩性,是因为它强制所有操作都是stateless的,这样就没有context的约束,如果要做分布式、做集群,就不需要考虑context的问题了。同时,它令系统可以有效地使用pool。REST对性能的另一个提升来自其对client和server任务的分配:server只负责提供resource以及操作resource的服务,而client要根据resource中的data和representation自己做render。这就减少了服务器的开销。
既然REST有这样的好处,那我们应该义无反顾地拥抱它啊!目前一些大牛(像DHH)都已经开始投入到了REST的世界,那我们这些人应该做什么或者说思考写什么你呢?我觉得我们应该思考两个问题:1)如何使用REST;2)REST和MVC的关系。 第一个问题假设REST是我们应该采用的架构,然后讨论如何使用;第二个问题则要说明REST和当前最普遍应用的MVC是什么关系,互补还是取代?

我们先来谈谈第一个问题,如何使用REST。我感觉,REST除了给我们带来了一个崭新的架构以外,还有一个重要的贡献是在开发系统过程中的一种新的思维方式:通过url来设计系统的结构。根据REST,每个url都代表一个resource,而整个系统就是由这些resource组成的。因此,如果url是设计良好的,那么系统的结构就也应该是设计良好的。对于非高手级的开发人员来说,考虑一个系统如何架构总是一个很抽象的问题。敏捷开发所提倡的Test Driven Development,其好处之一(我觉得是最大的好处)就是可以通过testcase直观地设计系统的接口。比如在还没有创建一个class的时候就编写一个testcase,虽然设置不能通过编译,但是testcase中的方法调用可以很好地从class使用者的角度反映出需要的接口,从而为class的设计提供了直观的表现。这与在REST架构中通过url设计系统结构非常类似。虽然我们连一个功能都没有实现,但是我们可以先设计出我们认为合理的url,这些url甚至不能连接到任何page或action,但是它们直观地告诉我们:系统对用户的访问接口就应该是这样。根据这些url,我们可以很方便地设计系统的结构。
让我在这里重申一遍:REST允许我们通过url设计系统,就像Test Driven Development允许我们使用testcase设计class接口一样。OK,既然url有这样的好处,那我们就着重讨论一下如何设计url。网络应用通常都是有hierarchy的,像棵大树。我们通常希望url也能反映出资源的层次性。比如对于一个blog应用:/articles表示所有的文章,/articles/1表示id为1的文章,这都比较直观。遗憾的是,网络应用的资源结构永远不会如此简单。因此人们常常会问这样一个问题:RESTful的url能覆盖所有的用户请求吗?比如,login如何RESTful?search如何RESTful?
从REST的概念上来看,所有可以被抽象为资源的东东都可以使用RESTful的url。因此对于上面的两个问题,如果login和search可以被抽象为资源,那么就可以使用RESTful的url。search比较简单,因为它会返回搜索结果,因此可以被抽象为资源,并且只实现index方法就可以了(只需要显示搜索结果,没有create、destory之类的东西)。然而这里面也有一个问题:search的关键字如何传给server?index方法显然应该使用HTTP GET,这会把关键字加到url后面,当然不符合REST的风格。要解决这个问题,可以把每次search看作一个资源,因此要创建create和index方法,create用来在用户点击“搜索”按钮是通过HTTP POST把关键字传给server,然后index则用来显示搜索结果。这样一来,我们还可以记录用户的搜索历史。使用同样的方法,我们也可以对login应用REST,即每次login动作是一个资源。
现在,我们来复杂一些的东东。如何用url表达“category为ruby的article”?一开始可能想到的是/category/ruby/articles,这种想法很直观。但是我觉得里面的category是不需要的,我们可以直接把“/ruby”理解为“category是ruby”,也就是说“ruby”出现的位置说明了它指的就是category。OK,/ruby/articles,单单从这个url上看,我们能获得多少关于category的信息呢?显然category隐藏在了url后面,这样做到底好不好,应该是仁者见仁,智者见智了。对于如何表达category这样的东西,我还没想出很好的方式,大家有什么好idea,可以一起讨论。
另外还有一种url形式,它对应到程序中的继承关系。比如product是一个父类,book和computer是其子类。那么所有产品的url应该是/products,所有书籍的url应该是/books,所有电脑的url应该是/computers。这一想法就比较直观了,而且再次验证了url可以帮助我们进行设计的论点。
让我再说明一下我的想法:如果每个用户需求都可以抽象为资源,那么就可以完全使用REST。
由此看来,使用REST的关键是如何抽象资源,抽象得越精确,对REST的应用就越好。因此,如何改变我们目前根深蒂固的基于action的思想是最重要的。
有了对第一个问题的讨论,第二个问题就容易讨论多了。REST会取代MVC吗?还是彼此是互补关系(就像AOP对于OOP)?答案是It depends!如果我们可以把所有的用户需求都可以抽象为资源,那么MVC就可以推出历史的舞台了。如果情况相反,那么我们就需要混合使用REST和MVC。当然,这是非常理想的论断。可能我们无法找到一种方法可以把所有的用户需求都抽象为资源,因为保证这种抽象的完整性(即真的是所有需求都可以)需要形式化的证明。而且即使被证明出来了,由于开发人员的能力和喜好不同,MVC肯定也会成为不少人的首选。但是对于希望拥抱REST的人来说,这些都没有关系。只要你开发的系统所设计的问题域可以被合理地抽象为资源,那么REST就会成为你的开发利器。
所以,所有希望拥抱REST的朋友们,赶快训练自己如何带上资源的眼镜看世界吧,这才是REST的核心所在。

http://foo.extremepattern.com/index.php?title=Hello_REST wiki: Hello REST
。。。REST 是一種風格 Style,不是一種技術 Technology。
http://foo.extremepattern.com/index.php?title=Hello_Restlet wiki:Hello Restlet 
。。。在整個嘗試過程中,最讓人難以確認是否做好的部份是在 URI 的設計,它必須是資源的獨一無二的地址,至於 Uniform Interface 的限制,反而容易做到,因為只有四個動詞。RESTify DayTrader 一文做了很好的示範,示範如何將動詞取出,分析名詞,設計 URI 標示資源與資源的操作方式。 
。。。How to Create a REST Protocol這篇文章提供很好的指引,這裡列出 RESTful Web Services 書中的建議步驟。 【虎.无名:推荐一看 http://www.xml.com/pub/a/2004/12/01/restful-web.html

  1. Figure out the data set
  2. Split the data set into resources
  3. Name the resuorces with URIs
  4. Expose a subset of the uniform interface
  5. Design the representation(s) accepted from the client
  6. Design the representation(s) served to the client
  7. Integrate this resource into existing resources, using hypermedia links and forms
  8. Consider the typical course of events:what's supposed to happen?
  9. Consider error conditions: what might go wrong?

HTTP Method CRUD Action Description POST CREATE Create a new resource GET RETRIEVE Retrieve a representation of a resource PUT UPDATE Update a resource DELETE DELETE Delete a resource

We'll update our table for our employee contact list to include the expected status codes

Resource Method Representation Status Codes Employee GET Employee Format 200, 301永久重定向, 410永久不可用 Employee PUT Employee Format 200, 301, 400错误请求, 410 Employee DELETE N/A 200, 204无消息体 All Employees GET Employee List Format 200, 301 All Employees POST Employee Format 201成功创建, 400

Warning Signs

Even following these steps, you could still make some mistakes. Paul Prescod has created a list of Common REST Mistakes that is worth reviewing as you work on your protocol.

http://www.prescod.net/rest/mistakes/ 【虎.无名:需要重视】When designing your first REST system there are a variety of mistakes people often make. I want to summarize them so that you can avoid them. If any are unclear, ask for more information on rest-discuss.

  1. Using HTTP is not enough. 【虎.无名:不仅仅把HTTP当作传输协议,而是一个应用协议。充分利用HTTP头信息和响应码。】
  2. Do not overuse POST. 【虎.无名:不要过渡使用POST方法,按需要使用DELETE和PUT,如果浏览器不支持,可以考虑客户端用ajax技术来实现。】
  3. Do not depend on URI's internal structure. 【虎.无名:URI是用户接口,只和用户需求相关,无需将URI绑定内部数据结构或数据库接口】
  4. Do not put actions in URIs. 【虎.无名:URI只和资源(名词)相关,与行为(动词)无关。】
  5. Services are seldom resources. 【虎.无名:服务很少是资源?一个资源可支持多种服务。也可这么理解:资源是一个类,而服务是类的一个方法。】
  6. Sessions are irrelevant. There should be no need for a client to "login" or "start a connection." HTTP authentication is done automatically on every message. Client applications are consumers of resources, not services. Therefore there is nothing to log in to! Let's say that you are booking a flight on a REST web service. You don't create a new "session" connection to the service. Rather you ask the "itinerary creator object" to create you a new itinerary. You can start filling in the blanks but then get some totally different component elsewhere on the web to fill in some other blanks. There is no session so there is no problem of migrating session state between clients. There is also no issue of "session affinity" in the server (though there are still load balancing issues to continue). 【虎.无名:登录认证似乎需要独立于REST系统,在前端WebServer上完成?】
  7. Do not invent proprietary(私有的) object identifiers. Use URIs. URIs are important because you can always associate information with them in two ways. 1)The simplest way is to put data on a web server so that the URI can be dereferenced in order to get the data. Note that this technique only works with URIs that can be dereferenced so these URIs (http URIs!) are strongly preferred to URN or UUID-based URIs. 2)Another way is to use RDF and other techniques that allow you to project metadata onto a URI that may not be under your control.
    If you use URI syntax with UUIDs or something like that then you get half of the benefit of URIs. You get a standardized syntax but have no standardized dereferencing capability. If you use an HTTP URI then you get the other half of the benefit because you then also have a standardized derferencing mechanism. 【虎.无名:没太明白,不要发明私有对象ID?】
  8. Do not worry about protocol independence. There exists only one protocol which supports the proper resource manipulation semantics. If another one arises in the future, it will be easy to keep your same design and merely support the alternate protocol's interface. On the other hand, what people usually mean by "protocol independence" is to abandon resource modelling and therefore abandon both REST and the Web. 【虎.无名:HTTP协议本身已经足够通用了】

Overall, the thing to keep in mind is that REST is about exposing resources through URIs, not services through messaging interfaces.【REST通过URL暴露资源,而不是通过消息接口暴露服务。虎.无名:暴露一个资源,是不是意味着该资源的所有操作都需要暴露?】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值