RESTful Web 服务:快速入门指南 - 第一部分
编写客户端以从面向响应的 RESTful 服务检索数据
PowerBuilder 12.5 .NET 的新功能之一是能够使用 WCF 调用 RESTful Web 服务。本文是两部分系列的第一部分,为 PowerBuilder 12.5 .NET 开发者提供了快速上手和构建 PowerBuilder RESTful Web 服务客户端所需的扎实知识和技能。在此过程中,我将与您分享一些技巧和变通方法。
引言
PowerBuilder 12.0 .NET 提供了使用 Microsoft 的 .NET 3.5 WCF API 调用基于 SOAP 的 Web 服务的功能。我鼓励那些不熟悉 WCF 和 SOAP 的用户查看我托管在 Sybase.com 上的 PowerBuilder WCF 入门教程和 StockTrader 参考应用程序概述。您可以通过 http://yakovwerde.ulitzer.com/node/1551687 访问我所有的免费教程。12.5 版本的新功能是,除了升级到 WCF 4.0 外,还增加了调用 RESTful Web 服务的能力,这是一种在 SOA 应用程序中访问远程资源的日益流行的机制。在本文中,我将帮助您获得一些基础知识和定义,然后让您熟悉编码客户端以从响应导向的 RESTful 服务检索数据的机制。在第二部分中,我将探讨三种类型的请求导向操作。
什么是 RESTful Web 服务?
简而言之,RESTful 服务是“Web 原生”且轻量级的。它们利用 HTTP 的原生 GET、PUT、POST 和 DELETE 方法在众所周知的 URI 上调用服务方法。关于 RESTful Web 服务的性质和实现以及它们与 SOAP/WSDL 服务的比较,互联网上已有大量免费信息。为了避免重复介绍已详尽描述的内容,列表 1 提供了一些 Web 参考,您可以从中了解该技术。如果您需要更多信息,在您喜欢的搜索引擎上进行快速搜索即可找到更多参考。如果您确实想深入研究,可以购买 Jon Flanders 编写的 O'Reilly 出版的《RESTful .NET》。
从客户端角度看,WSDL / SOAP 服务和 RESTful 服务之间的一个实际区别是客户端开发人员的责任大小。SOAP 服务在 WSDL 文档中得到完全描述,包括其服务方法、输入参数和返回类型。PowerBuilder 开发者除了将 WSDL 位置输入向导或项目 Painter 并单击生成代理按钮外,别无他责。项目 Painter 会处理其余的事情。SOAP 调用也是基于方法的。运行时,开发者实例化一个代理并根据需要调用特定方法。然而,对于 RESTful 服务,开发者在定义接口方面承担更多责任。他必须获取一个模式(XSD)文档或 .NET 程序集,该文档或程序集完全描述了返回的 XML 或 JSON 中的类型,或者获取一个具有足够变化数据的样本结果集,以便代理生成器能够解读返回结构。他还必须对返回类型的结构有足够的了解,以便能够检查向导的工作并根据需要进行更正(稍后会详细介绍)。对 RESTful 服务的调用不是基于方法的——只需在服务 URI 后面附加正确的参数即可获得响应。这意味着每个服务(方法)都有一个代理,因此需要维护更多的代码对象。
什么是 JSON?
根据实现方式的不同,RESTful Web 服务可以返回多种标准格式的数据。可能的格式包括 XML、CSV、RSS、ATOM 和 JSON。PowerBuilder 12.5 允许您选择 XML 或 JSON 作为传输格式。什么是 JSON?简而言之,JSON 是一种对 JavaScript / AJAX 浏览器友好的数据传输格式。由于 AJAX 是一种普遍的 Web 技术,许多服务仅提供 JSON 格式。列表 2 提供了一些有用的参考,您可以从中获得更多关于 JSON 的背景知识。
JSON 对 PowerBuilder 毫无问题!在设计时,您可以向项目 Painter 提供 JSON 或 XML 格式的样本数据集。项目 Painter 将解析样本数据,JSON 数据并生成您需要处理数据的 .NET 引用对象。运行时,JSON 数据传输将被解析并转换为 .NET 值对象。好消息是,作为 PB 程序员,您不必编写 JSON;但是,您将不得不阅读它来理解结果集的构造方式。
查看 JSON
IE 9 没有原生的 JSON 数据查看功能。您需要使用工具来查看输出数据。其中一个工具是 http://www.jsonviewer.com/。进入页面后,输入完整的调用 URL,然后点击“Get JSON and Parse”按钮。图 1 显示了您可能会看到的内容。
如果您使用 Fiddler 监控 HTTP 流量(http://www.fiddler2.com/fiddler2),请安装 JSON 查看器。图 2 显示了如何在 Fiddler 中查看返回的 JSON 对象。
开始使用 PowerBuilder RESTful 客户端
侧边栏提示
PowerBuilder 依赖 .NET 4.0 SDK 中的工具来生成您的客户端应用程序所需的许多代码构件。在撰写本文时,12.5 是 Beta 测试版。安装程序不安装 .NET 4.0 SDK。您需要从 Microsoft 下载并安装 .NET 4.0 SDK。如果您的系统上未安装 SDK,当您尝试生成代理时将收到一条错误消息。
在本教程中,我将使用位于 www.GeoNames.org 的免费 GeoNames 服务。GeoNames 地理数据库覆盖许多国家,包含超过八百万个地名,可免费下载。GeoNames 通过一套强大的 RESTful 服务提供对该数据库的访问。图 3 显示了可用服务的部分列表。您可以在 http://www.geonames.org/export/ws-overview.html 找到可用服务的完整列表。要自行探索 GeoNames,您需要通过其主页右上角的“Login”链接创建一个免费用户帐户。拥有帐户很重要,因为您需要在服务调用中提供您的用户名作为参数,并且使用“demo”用户名进行访问会受到极大限制。
入门
在 RESTful 服务项目向导中输入信息之前,您需要准备好以下信息:
- 您希望将项目对象保存在哪个 PBL 中(通常是生成 EXE 的项目对象所在的同一个 pbl)。
- 项目 Painter 将为您的代理类生成代码的 PBL(您可能希望为代理使用单独的 pbl,以便在需要时进行批量刷新)。
- Web 方法类型 GET、POST、PUT 或 DELETE。
- 您的代理类的名称。您将在代码中与此类进行交互。我建议在名称中使用 `P_` 前缀。
- 您想将代理类放在哪个命名空间中——您可以将其留空以使用默认命名空间。
- 服务 URI,包括调用所需的任何参数。
- 服务的返回数据格式:XML 或 JSON。
- 要生成的程序集的名称。此程序集将包含用作参数和/或返回类型的值对象。向导将将其作为引用添加到您的目标中。此名称也将成为程序集的命名空间。
- 一个源,用于帮助 Painter 确定返回数据类型。有三个选项,请选择一个:
- 定义返回数据集结构的模式文档(XSD)。
- 正式定义返回类型结构的预先存在的程序集。
- 一个 XML 片段或 JSON 对象样本,其数据足够丰富和健壮,以至于工具可以从其内容中推断出数据类型。
侧边栏提示
如图 4 所示,通过更改服务 URL 字面值并将其替换为标记,您可以使生成器在 `GetMessage()` 方法中包含输入参数。`{ }` 中的标识符将成为参数名称。如果您保留字面值,生成器将发出一个无参数的方法调用。
逐步操作向导
创建新的代理类是一个两步过程。首先,您运行向导以生成开发时项目对象和引用程序集。然后,您在项目 Painter 中验证输入,并部署项目对象以生成运行时代码构件。我将引导您完成该过程。在此示例中,我将对 GeoName findNearbyWikipedia 服务执行 GET 操作。请按顺序查看图 5 到图 12,以概览整个过程。
侧边栏提示
GET 方法的调用名称始终是 `GetMessage()`。将服务名称作为其相应代理类名称的一部分包含在内是一个好习惯。这将使其意图清晰。
侧边栏提示
如果您使用样本数据集(XML 或 JSON)来生成引用程序集,那么检查发出的程序集以验证每个属性的数据类型非常重要。有时 Microsoft 解析器会错误地解释属性的类型。在继续之前,您应该进行更正。引用程序集没有中间源代码,因此您唯一的办法是向项目对象提供会导致其正确渲染属性的值。例如,一个值为 '07960' 的 postalCode 元素被生成为 UInt16 而不是预期的 String 类型。提供值 'x7960' 会强制该类型被渲染为 String。
生成的构件
让我们更深入地了解生成的代码构件。图 13 显示了从项目对象生成的三个对象类别。
项目对象是用于输入您的选择的场所,也是 Microsoft 和 PowerBuilder 代码生成工具的前端。您需要点击项目对象 PainterBar 上的“生成代理”按钮来启动代码生成过程。
代理类是您在代码中实例化并用于调用服务的类。请勿修改生成的代码。您对此代码对象所做的任何更改都将在重新生成代理时丢失。要扩展或修改此代码,请继承此类并在派生类中编写您的更改。您实例化一个代理类型对象并调用 `GetMessage()`,传递适当的参数来调用服务。图 14 显示了一个典型的代理类,用于调用 GET 方法。
请求和响应程序集包含 GET 调用返回的值对象,或作为 DELETE、POST 和 PUT 调用的参数传递的值对象。WCF 基础结构负责将 JSON 和 XML 转换为值对象,反之亦然。您无需处理低级转换问题。通常会有一个包装器对象,该对象可能包含或不包含数据属性。它相当于 XML 文档中的根元素。包装器对象将包含一个值对象数组。这些是重复的行导向的 XML 结构。值对象将包含一组特定于返回的数据值。图 15 显示了一个典型的响应程序集的内容。
脚本调用
运行时代码算法遵循以下步骤:
- 在适当的作用域中实例化代理。
- 声明返回值引用变量。
- 调用 `GetMessage()` 方法,传递适用的参数并捕获返回值。
- 销毁代理或让其超出作用域。
图 16 显示了一个 GET 服务调用的完整代码。当然,在“真实”应用程序中,您会对返回值做比在消息框中显示更重要的事情。
请注意,即使在设计良好的应用程序中,也可能发生超出客户端开发人员控制范围的事情。例如,运行时服务可能宕机或在已知 URI 上完全不可用。因此,即使异常处理是可选的,最好也使用 TRY CATCH 块来脚本化服务调用,以避免运行时系统错误,并包含一个健壮的处理器来处理有问题的条件。
侧边栏提示
使用单行 DataWindow 表达式直接从 PowerScript NVO 数组加载数据缓冲区效果很好。但是,直接使用表达式将 .NET 值对象数组分配给 DataWindow 缓冲区会引发运行时错误。因此,您必须采取更耗时、更费力的代码方法。您必须(a)迭代 .NET 对象数组并为每个值调用 `SetItem()`,或者(b)将 .NET 值数组分配给等效的中间 PowerScript NVO 类型数组,然后将其分配给 DataWindow。
侧边栏提示
不幸的是,Web Service DataWindow Objects 仅支持 SOAP。它们尚未实现 RESTful 感知。要使用 DataWindow 进行数据显示,您需要声明一个外部数据源 DataWindow,并手动从 RESTful WS 调用返回中填充其缓冲区。
结论
RESTful 服务在 Web 上日益普及。许多流行服务(如 Google 和 Yahoo)的 API 都可以作为 RESTful 服务使用。PowerBuilder 12.5 .NET 程序员现在能够使用标准工具和技术将 RESTful 服务调用集成到他们的应用程序中。
PowerBuilder 万岁!