CA1S 中的 REST 基础
SupportPac CA1S 中的 REST 式事件处理程序
概述
WebSphere sMash 引入了一组约定,它们简化了 REST 式 Web 服务的创建(要了解更多信息,请从 参考资料 中阅读 WebSphere sMash 文档)。SupportPac CA1S 采用了这些约定的其中一部分,并且在 CA1S 文档中详细描述(见 参考资料),但可概括为:
- 可将 CA1S 配置为以 REST 方式处理某些路径的请求。在默认的 CA1S 安装中,这个特性适用于 /ca1s/resources 下的路径。
- 当在这种路径上的请求被处理时,将按照以下方式从 URI 发出关于目标源的信息:
http://<host>/ca1s/resources/<resourceName>[/<resourceID>[/<…more/resource/info…>]]
|
- 将查找与资源名称对应的资源处理程序脚本。PHP 引擎将执行该脚本,然后尝试在脚本内部调用一个特定的方法,这取决于请求的 HTTP 方法和 URI 是否在资源名称之后包含一个标识符。
表 5 显示了从 HTTP 请求类型到将要调用的方法的映射,假设资源的名称为 “book”:
表 5. REST 式事件处理程序方法
|
请求 URI
| HTTP Method | Handler method
invoked in ca1s/work/resources/book.php |
集合 URI,例如
http://<host>/ca1s/resources/book
|
GET
|
book::onList()
| | |
POST
|
book::onCreate()
| | | PUT |
book::onPutCollection() | | | DELETE |
book::onDeleteCollection() |
成员 URI,例如
http://<host>/ca1s/resources/book/10
|
GET
|
book::onRetrieve()
| | | POST | book::onPostMember()
| | |
PUT
|
book::onUpdate()
| | |
DELETE
|
book::onDelete()
|
资源处理程序脚本不需要实现表 5 中的所有方法。如果没有找到特定事件的方法,也不会引起错误。最常实现的事件处理程序是与资源上的 List、Create、Retrieve、Update 和 Delete(LCRUD)操作对应的事件的处理程序,在表 5 中用粗体表示它们。
示例
清单 6 中的示例为每个事件输出不同的字符串: 清单 6. 资源处理程序脚本的主体结构
<?php
class book {
function onList() {
echo 'LIST all books!';
}
function onCreate() {
echo 'CREATE a book!';
}
function onRetrieve() {
echo 'RETRIEVE a book!';
}
function onUpdate() {
echo 'UPDATE a book!';
}
function onDelete() {
echo 'DELETE a book!';
}
}
?>
|
如果要测试它,请将以上的脚步复制到您的 CICS 系统的 ca1s/work/resources/book.php(注意,在脚本中声明的类名必须与脚本文件名匹配)。然后使用 REST 客户端(比如 Poster add-on for Firefox)通过不同的 HTTP 方法访问它(是否对 URI 使用标识符)。您将看到事件处理程序被正确触发。例如:
图 2. 图书资源中带有标识符的 GET 请求触发 onRetrieve() 事件处理程序
图 3. 图书资源中不带标识符的 POST 请求触发 onCreate() 事件处理程序
事件处理程序未被调用?
确认以下所有表述都是相同的(它们都表示资源名):
- 在 ‘ca1s/resources/’ 前缀之后的请求 URI 的第一个路径组件
- 针对 .php 扩展的资源处理程序脚本的文件名
- 在脚本中定义的类的名称
使用 zget() 访问请求数据
脚本可能使用 CA1S 内置的 zget() 函数访问入站请求的各种属性。其中的例子包括:
- 入站请求的主体作为字符串,从请求编码转换为 PHP 运行时编码:
$data = zget('/request/input/transcoded'); |
- 查询字符串参数(以及 POST 和 PUT 参数,如果它们经过了格式编码):
$value = zget('/request/params/<paramName>');
|
$id = zget('/request/params/<resourceName>Id');
|
- 资源 ID 之后的 URI 部分(如果可用的话):
$data = zget('/event/pathInfo');
|
如果要使用 zget(),请按照以下方式修改 book.php 中的 method book::onUpdate():
function onUpdate() {
$id = zget('/request/params/bookId');
$data = zget('/request/input/transcoded');
echo "You attempted to update book $id with data $data";
}
|
然后,使用 PUT 请求访问一个特定的图书资源,以触发更新事件。
图 4. 使用 Poster 测试 zget
zget() 函数基于 WebSphere sMash 中的 Global Context 特性(见 参考资料)。CA1S 文档描述了 zget() 在 CA1S 中提供的完整函数,并且与 WebSphere sMash 中的版本进行了比较。您还可以使用 PHP 的标准机制访问请求数据,比如 $_GET superglobal 和 php://input 流等等。
使用 JSON 作为服务数据的交换格式
REST 为将资源公开为服务定义了一个简单一致的接口,但它没有为服务的输入输出数据指定某种格式 — 这由实现者决定。JSON 是一个很受欢迎的选择,因为它很简单、可读性强,并且受许多客户端和服务器端语言的支持。
将 PHP 变量编码为 JSON 数据
下面的代码清单显示了 onRetrieve() 处理程序如何发送编码为 JSON 字符串的图书资源。注意,在这个例子中,为了保持简单性,我们将图书细节硬编码到处理程序中。在下一小节中,您将看到如何从 COBOL 书库程序获取该信息。
function onRetrieve() {
$id = zget('/request/params/bookId');
// ... establish that book with ID $id is Heart of Darkness ...
$book['title'] = 'Heart of Darkness';
$book['author'] = 'Joseph Conrad';
echo json_encode($book);
}
|
向成员 URI(比如 /ca1s/resources/book/10)发出的 GET 请求的响应体包含:
{"author":"Joseph Conrad","title":"Heart of Darkness"}
|
解码 JSON 数据 那么,onCreate() 处理程序如何处理在请求中编码为 JSON 的输入数据呢?在这里,为了保持简单,我们仅仅输出解码后的数据;在实际场景中,我们将使用该数据创建一个新的资源。
function onCreate() {
$inputData = zget('/request/input/transcoded');
$book = json_decode($inputData, true);
// ... Create new book resource based on data in $book ...
// Dump out the variable to illustrate:
var_dump($book);
}
|
在 POST 请求体中将类似于
{"author":"Margaret Atwood","title":"Oryx and Crake"}
|
的数据发送到集合 URI ca1s/resources/book 中,这将返回:
array(2) {
["author"]=>
string(15) "Margaret Atwood"
["title"]=>
string(14) "Oryx and Crake"
}
|
|