构建 RESTful Web 服务
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
构建RESTful Web 服务
开始之前
关于本教程
REST 是一种思维方式,而非协议或标准。它是设计基于命名资源而非消息的松耦合应用程序—通常指面向Web 的应用程序—的一种风格。在本教程中,您将了解到何为REST 以及如何使用Restlet(一个面向Java™ 应用程序的轻量级框架)构建RESTful 应用程序。
目标
本教程从REST 的基本概念开始逐步指导您使用Restlet 构建应用程序。您将学习如何:∙定义RESTful Web 服务
∙用Restlet 框架实现它们
∙用JUnit 测验框架验证它们
学完本教程后,您就会领会到使用RESTful 原则进行设计的益处,了解到Restlet 框架是如何轻松地实现它们的。
先决条件
为了更好地学习本教程,您需要熟悉Java 语法以及Java 平台中面向对象开发的基本概念。还要熟悉Web 应用程序。熟悉Groovy、Unit、DbUnit 和XMLUnit 对此也很有帮助。
系统需求
要跟随并试用本教程中的代码,您需要如下列出的任意一种可行的安装:∙Sun's JDK 1.5.0_09(或更高版本)
∙IBM Developer Kit for Java technology 1.5.0 SR3
∙Apache Ant 1.7 或者更高级版本
本文的源代码有两种版本(参见下载)。其中一个版本包含了全部代码以及所需依赖项(Restlet 框架JUnit、XMLUnit 和DbUnit)。使用低带宽连接的读者可以从它们各自的站点分别下载Restlet 框架、JUnit、XMLUnit 和DbUnit(参见参考资料)并使用不包含依赖项的下载包。
要学习本教程,推荐的系统配置为:
∙支持Sun JDK 1.5.0_09(或更新版本)或者IBM JDK 1.5.0 SR3 的系统,主内存至少为500MB
∙有至少20MB 的磁盘空间安装软件组件和涉及到的示例
本教程中的指令和示例基于Microsoft® Windows® 操作系统。教程中所用到的所有工具在Linux® 和UNIX® 系统上都可以运行。
何为REST?
REST 是设计基于命名资源—例如,以Uniform Resource Locators(URL)、Uniform Resource Identifiers(URI)和Uniform Resource Names(URN)的形式—而非消息的松耦合Web 应用程序的一种风格。REST 巧妙地借助已经验证过的成功的Web 基础设施— HTTP。换句话说,REST 利用了HTTP 协议的某些方面,例如GET和POST请求。这些请求可以很好地映射到标准业务应用程序需求,诸如创建、读取、更新和删除(CRUD),如表1 所示:
表1. CRUD/HTTP 映射
应用程序任务HTTP 命令
创建POST
读取GET
更新PUT
删除DELETE
请求就像是动词,而资源就像是名词,把两者相关联就形成了对行为的逻辑表达—例如, GET这个文件,DELETE那条记录。
真正的REST 之父Roy Fielding 在他的博士毕业论文中陈述到:REST “强调组件交互的可伸缩性、界面的普遍性、独立部署组件以及使用中间组件来减少交互延迟,增强安全性并封装遗留系统”(参见参考资料)。构建RESTful 系统并不难,且这样的系统具有高度的可伸缩性,同时与底层数据松散耦合;这样的系统还可以很好地利用缓存。
Web 上所有的东西(页面、图像等)本质上都是资源。而REST 正是基于命名资源而非消息的,这就限制了底层技术的曝光,从而给应用程序设计中的松耦合提供了便利条件。例如,下面的URL 在不暗示任何底层技术的情况下,公开了资源:
/2008/03/20/unambiguously-analyzing-metrics/。
该URL 表示一个资源—一篇名为“Unambiguously analyzing metrics” 的文章。请求该资源就会调用HTTP GET命令。注意该URL 是基于名词的。基于动词的版本(大概类似/2008/03/20/getArticle?name=unambiguously-analyzing-metrics)会违反REST 原则,因为它以getArticle 的形式嵌套了一条消息。您也可以设想通过HTTP 的POST命令来发布一个新资源,(比如说,一篇诸如
/2008/03/22/rest-is-good-for-you/ 的文章)。你还可以设想用关联的、基于动词的API —如createArticle?name=rest-is-good-for-you and deleteArticle?name=rest-is-good-for-you —这样的调用来拦截HTTP GET命令,并最大限度地忽略已有的(并且是成功的)HTTP 基础设施。换句话说,它们不是RESTful 风格。REST 的魅力在于任何东西都可以成为资源,且表示方法也可以不同。在前面的例子中,资源为一个HTML 文件,因此,其响应可能是HTML 格式的。但是资源也可以是一个XML 文档、序列化的对象或者JSON 表示。其实,这些都无关紧要。重要的是资源被命名了,并且与它通信不会影响其状态。不影响状态是很重要的,因为无状态的交互有利于可伸缩性。
、
它的价值在那里?
引用达芬奇的一句名言“简洁就是终极复杂”。万维网的实现非常简单,并且无可置否地获得了成功。REST 正是利用了Web 的简单性,并因此造就了高度可伸缩的、松散耦合的系统,而且事实证明,这样的系统很容易构建。
正如您所看到的,构建RESTful 应用程序最难的部分在于确定要公开的资源。解决了这个问题之后,再使用开源Restlet 框架构建RESTful Web 服务就是小菜一碟了。
起跑:构建一个RESTful API
在本节中,您将为一个Web 服务构建一个RESTful API,该服务利用了支持数据库的现有应用程序的功能。
RESTful 比赛
设想这样一个在线应用程序,它管理赛跑比赛,参赛人员要跑完不同的路程(比如芝加哥马拉松赛跑)。应用程序管理赛跑(或者赛事)以及与其相关的参赛人员。它会报告某个选手的时间(跑完全程所用的时间)和排名(参赛人员以第几名跑完全程)。赛事筹办公司Acme Racing 要求您构建一个RESTful Web 服务,主办方可以用它来为特定比赛安排新的赛事和选手,并且可以为某次特定比赛提供官方记录。
Acme Racing 已经有了一个遗留的胖客户机应用程序,它支持类似的请求,并利用了一个简单的数据库和一个域模型。因此,剩下的工作就只有公开这个功能了。记住REST 的魅力就在于它与底层应用程序的隐式松散耦合。因此,您目前的工作并非是去操心数据模型或与其相关联的技术—而是去构造一个支持公司需求的RESTful API。
比赛URI
Acme Races 希望主办方能够:
∙查看现有比赛细节
∙创建新的比赛
∙更新现有比赛
∙删除比赛
由于REST 最终归结为命名资源,API 就成为了一系列URI 模式,并且与资源相关联的行为要通过标准HTTP 命令调用。
正如您可以看到的,客户的请求很好地映射到了CRUD。并且如您在表1中所了解到的一样,REST 分别通过HTTP 的POST、GET、PUT以及DELETE请求来支持CRUD。因此,一个支持这些请求的基RESTful URI 应为/race。注意,在这种情况下,比赛是客户机要使用的资源。
用HTTP GET来调用URI 会返回一个比赛列表(这时先不要考虑响应的格式)。要添加新比赛,要用包含适当信息(例如,一个包含诸如名称、日期和距离等信息的XML 文档)的HTTP POST来调用同一URI。
要更新和删除现有比赛,则需要对特定比赛的实例进行操作。因此,可以给单个比赛赋予一个URI:/race/race_id。在这种情况下,race_id表示任一比赛标识符的一个占位符(诸如1 或者600 米)。因此,查看一个现有比赛实例就是针对该URI 执行一个HTTP GET请求;更新或者删除一个比赛分别为一个PUT或
者DELETE请求。