RESTful初识
这阵子正打算用Rails做个东东,所以开始系统地学习起了Rails。巧合的是,大概两周前,dlee邀请我加入Fielding博士关于REST的那
篇论文的翻译团队。可以说Rails和REST这两个最热门的词汇几乎同时挤入了我的生活。随着我对Rails的学习和对[Fielding]的翻译,我
也开始对REST产生了一些不太成熟的想法,写在这里与大家分享,同时也起到抛砖引玉的作用,欢迎大家讨论。
先复习一下REST的基本思想。[Fielding]把REST形式化地定义为一种架构风格(architecture
style),它有架构元素(element)和架构约束(constraint)组成。这些概念比较晦涩难懂,而且我们做工程的往往并不需要形而上的理
解。我们只知道,REST是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。REST提出了一些设计概念和准则:
网络上的所有事物都被抽象为资源(resource);
每个资源对应一个唯一的资源标识(resource identifier);
通过通用的连接器接口(generic connector interface)对资源进行操作;
对资源的各种操作不会改变资源标识;
所有的操作都是无状态的(stateless)。
对于当今最常见的网络应用来说,resource identifier是url,generic connector
interface是HTTP,第4条准则就是我们常说的url不变性。这些概念中的resouce最容易使人产生误解。resouce所指的并不是数
据,而是数据+特定的表现形式(representation),这也是为什么REST的全名是Representational State
Transfer的原因。举个例子来说,“本月卖得最好的10本书”和“你最喜欢的10本书”在数据上可能有重叠(有一本书即卖得好,你又喜欢),甚至完
全相同。但是它们的representation不同,因此是不同的resource。
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的世界,那我们这些人应该做什么或者说思考写什么你呢?我觉得我们应该思考两个问题:
如何使用REST;
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的核心所在。
转载自javaeye论坛 作者:AllenYoung
分享到:
相关推荐
另外,ASP.NET Web API用于构建RESTful服务,便于移动设备和Web应用之间的数据交换。近年来,ASP.NET Core成为主流,它跨平台、高性能且模块化,可以运行在Windows、Linux和macOS上。 本教程的PDF版本可能包含了...
3. **路由系统**:tp5的路由系统允许开发者定义URL到特定控制器和方法的映射,使得URL结构更加清晰,同时也方便了API的设计和RESTful风格的应用开发。 4. **微信小程序开发**:微信小程序是一种无需下载安装即可...
- `@PathVariable`:用于处理 RESTful 风格的 URL 中的占位符。 - `@ModelAttribute`:用于绑定表单数据到 Model 对象。 6. **数据绑定与验证** - Spring 提供了数据绑定机制,能自动将请求参数映射到方法参数。...
**初识SpringMVC** SpringMVC是Spring框架的一个模块,专为构建Web应用程序而设计。它是一个基于模型-视图-控制器(MVC)架构的轻量级Java Web开发框架,提供了处理HTTP请求和响应的强大功能。在本文中,我们将深入...
ASP.NET Web API是用于构建RESTful服务的框架,它可以创建HTTP服务,供各种客户端(如浏览器、移动设备或桌面应用)调用。Web API支持JSON和XML数据格式,方便与现代前端框架集成。 7. **ASP.NET Core** ASP.NET ...
本笔记将深入探讨如何在SpringMVC中创建RESTful的API。 1. **REST原则** - 统一接口:REST接口应具有统一的格式,通常使用HTTP方法(GET、POST、PUT、DELETE等)来表示操作。 - 状态转换:每个请求都包含完成操作...
- **API 接口服务**:借助 restify 或其他框架可以构建高性能的 RESTful API 服务。 - **数据库操作**:连接并操作 MySQL、MongoDB 等数据库。 - **命令行工具**:创建用于辅助前端开发的命令行工具。 - **等等**:...
**XFire初识:使用Eclipse开发WebService** 在IT行业中,WebService是一种允许应用程序之间进行交互的标准化技术。它通过XML(可扩展标记语言)来交换数据,使得不同平台上的应用能够无缝对接。XFire是Java平台上一...
- **Web开发**:学习如何使用Spring MVC构建RESTful API,处理HTTP请求。 - **数据库集成**:使用JPA或MyBatis进行数据访问,理解事务管理。 - **Spring Boot测试**:学习单元测试和集成测试,确保代码质量。 - ...
**初识Flask-Restful** 1. **安装扩展**:同样,先通过pip安装Flask-Restful: ``` pip install Flask-Restful ``` 2. **创建Resource**:Flask-Restful的核心是Resource类,继承自它并定义处理请求的方法: `...
一直没有好好看过jwt,直到前两天要做web验证,朋友给我推荐了jwt。才发现jwt已经被大家广泛的应用了。看来我有点out了。哈哈,趁着这个世界来好好看看这个。 JWT(JSON Web Token), ...可以说 restful api认证是jwt的一
【Spring Boot框架初识与快速入门】 Spring Boot是一款由Pivotal团队开发的框架,旨在简化Spring应用的初始搭建以及开发过程。它采用"约定优于配置"的理念,减少了大量传统Spring应用所需的XML配置,使开发者能更...
【初识Laravel】 Laravel 是一款流行的开源Web应用程序开发框架,它的设计灵感来源于其他诸如Ruby on Rails、ASP.NET MVC和Sinatra等框架,旨在提供一个优雅、高效的开发环境,让开发者能够专注于创新而非繁琐的...
【初识Django】 Django是一个用Python编写的高级Web框架,它遵循“ batteries included ”的理念,即在标准安装中提供了许多内置功能和组件,帮助开发者快速构建高效、可维护的Web应用。Django的设计模式主要基于...
《初识JavaEE 5:从新手到专家》是一本专为Java EE 5初学者设计的优秀教程。这本书深入浅出地介绍了Java企业版5(Java EE 5)的各种核心技术,旨在帮助读者快速掌握这一强大的企业级开发平台。Java EE 5是Java应用...
9. **Web服务**:通过JAX-WS和JAX-RS,J2EE支持创建和消费SOAP和RESTful Web服务。 **学习路径** 对于想要深入理解JSP和J2EE的开发者,通常会从基础的HTML、CSS、JavaScript开始,然后学习Servlet和JSP,逐步掌握EL...
第一部分是初识Python编程基础,包括语言排行榜、技术雷达、Python之禅等基础知识。第二部分是认识自动化测试,包括自动化测试的场景和特点、类型、要学什么等内容。第三部分是单元测试,包括单元测试介绍、测试框架...
《初识Java™ EE 6平台与GlassFish™ 3:从新手到专业》这本书是为那些想要深入了解Java企业级应用开发的初学者和进阶者准备的。它全面覆盖了Java EE 6平台的核心技术和GlassFish服务器的使用,帮助读者从零基础开始...