使用 JavaScript 编程 API 代理

您正在查看 Apigee Edge 文档。
前往 Apigee X 文档
信息

在本主题中,您将学习如何使用 JavaScript 动态向响应消息添加 HTTP 标头,以及如何解析 JSON 响应并将其部分属性返回给请求应用。

下载并试用示例代码

关于此实战宝典示例

此 Cookbook 示例展示了一种 API 代理模式,您可以在其中使用 JavaScript 实现 API 行为。这些 JavaScript 示例旨在向您展示如何处理简单变量和消息内容。其中一个示例展示了如何获取设置变量。第二个示例展示了如何解析 JSON 并根据结果构建消息。

API 代理中有两个 JavaScript 示例:

  • setHeaders.js:此 JavaScript 会获取在调用 API 代理时设置的几个变量的值。JavaScript 会将这些变量添加到响应消息中,以便您查看所发出的每个请求的变量值。
  • minimize.js:此 JavaScript 代码展示了如何处理消息内容。此示例背后的理念是,服务通常会返回比必要更多的数据。因此,JavaScript 会解析响应消息,提取一些有趣的属性,然后使用这些属性来构建响应消息的内容。

setHeader.js 的代码:

context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"));
context.setVariable("response.header.X-Apigee-ApiProxyName", context.getVariable("apiproxy.name"));
context.setVariable("response.header.X-Apigee-ProxyName", context.getVariable("proxy.name"));
context.setVariable("response.header.X-Apigee-ProxyBasePath", context.getVariable("proxy.basepath"));
context.setVariable("response.header.X-Apigee-ProxyPathSuffix", context.getVariable("proxy.pathsuffix"));
context.setVariable("response.header.X-Apigee-ProxyUrl", context.getVariable("proxy.url"));

minimize.js 的代码:

// Parse the respose from the target.
var res = JSON.parse(context.proxyResponse.content);

// Pull out only the information we want to see in the response.
var minimizedResponse = { city: res.root.city,
                          state: res.root.state };
          
// Set the response variable. 
context.proxyResponse.content = JSON.stringify(minimizedResponse);

您可以通过上下文对象在 JavaScript 中访问流变量。此对象是 Edge JavaScript 对象模型的一部分。如需详细了解对象模型,请参阅 JavaScript 对象模型

准备工作

在探索此 Cookbook 示例之前,您还应熟悉以下基本概念:

  • 政策是什么以及如何将其附加到代理。如需简要了解政策,请参阅什么是政策?
  • 代理流的结构,如配置流中所述。通过流,您可以指定 API 代理执行政策的顺序。在此示例中,我们创建了多个政策并将其添加到了 API 代理流中。
  • API 代理项目在文件系统中的组织方式,如 API 代理配置参考中所述。
  • 熟悉 XML、JSON 和 JavaScript。在此示例中,您将使用文件系统中的 XML 文件构建 API 代理及其政策。

如果您已下载示例代码,则可以在 javascript-cookbook 示例文件夹中找到本主题中讨论的所有文件。以下部分将详细讨论示例代码。

了解代理流程

如需在 API 代理中执行 JavaScript,您必须使用称为“步骤”的政策附件将其附加到流。类型为 Javascript(注意大小写)的政策仅包含对 JavaScript 文件名称的引用。您可以使用 Resource网址 元素将政策指向 JavaScript 文件。

例如,以下政策引用了名为 setHeader.js 的 JavaScript 文件。

<Javascript name='setHeaders' timeLimit='200'>
    <ResourceURL>setHeaders.js</ResourceURL>
</Javascript>

您可以像附加任何其他类型的政策一样,将此政策附加到 API 代理流。通过将政策附加到 API 代理流,您可以指明 JavaScript 应在何处执行。这样一来,您就可以执行 JavaScript,让其在请求消息或响应消息通过 API 代理“流动”时与这些消息进行交互。在此示例中,两个 JavaScript 都会在响应流中执行,因为相应政策会执行两项操作:在响应消息中设置 HTTP 标头,以及“最小化”Apigee Edge 返回给请求应用的响应消息。

如果您在管理界面中打开此流配置,您将看到以下流配置。

导航器窗格中,选择代理端点 > 默认 > PostFlow

名为“default”的 ProxyEndpoint 的相应 XML 配置如下所示。

<ProxyEndpoint name="default">
  <PostFlow>
    <Response>
      <!-- Steps reference policies under /apiproxy/policies -->
      <!-- First, set a few HTTP headers with variables for this transaction. -->
      <Step><Name>setHeaders</Name></Step>
      <!-- Next, transform the response from XML to JSON for easier parsing with JavaScript -->
      <Step><Name>transform</Name></Step>
      <!-- Finally, use JavaScript to create minimized response with just city and state. -->
      <Step><Name>minimize</Name></Step>
    </Response>
  </PostFlow>
  <HTTPProxyConnection>
        <!-- BasePath defines the network address for this API proxy. See the script 'invoke.sh' to see how the complete URL for this API proxy is constructed.-->
    <BasePath>/javascript-cookbook</BasePath>
     <!-- Set VirtualHost to 'secure' to have this API proxy listen on HTTPS. -->
    <VirtualHost>default</VirtualHost>
  </HTTPProxyConnection>
  <RouteRule name="default">
    <TargetEndpoint>default</TargetEndpoint>
  </RouteRule>
</ProxyEndpoint>

下面简要介绍了该流程的各个元素。

  • <Request> - <Request> 元素包含多个 <Step> 元素。每个步骤都会调用您在本主题的其余部分中创建的政策之一。这些政策会将 JavaScript 附加到 API 代理流,而政策附加的位置决定了 JavaScript 的执行时间。
  • <Response> - <Response> 元素还包含 <Steps>。这些步骤还会调用负责处理来自目标的最终响应的政策(在此示例中,目标是 Apigee 的模拟服务目标 - 请注意 /apiproxy/targets/default.xml 下的 HTTPTargetConnection 设置)。
  • <HTTPProxyConnection> - 指定用于定义应用调用以使用此 API 的网络地址的主机和 URI 路径。
  • <RouteRule> - 此元素用于指定 ProxyEndpoint 调用哪个 TargetEndpoint 配置。

向代理添加 JavaScript 代码

JavaScript(与 Python 脚本、Java JAR 文件、XSLT 文件等一样)存储为资源。如果您刚开始使用 JavaScript,最简单的方法是将 JavaScript 文件存储在 API 代理中。随着您不断进步,JavaScript 应尽可能通用且可重复使用,然后存储在环境组织级层。这样一来,您就不必在多个 API 代理中存储相同的 JavaScript 文件,否则很快就会变得难以管理。

如需了解如何在组织和环境级层存储资源,请参阅资源文件

试试看

如需了解有关部署和调用代理的说明,请参阅 JavaScript 食谱自述文件

导入和部署 API 代理

做出更改后,您可以在管理界面的 API 代理构建器工具中保存 API 代理。

或者,您可以在目录 /api-platform-samples/doc-samples/javascript-cookbook 中运行以下命令。

$ sh deploy.sh

测试 JavaScript

在目录 /api-platform-samples/doc-samples/javascript-cookbook 中运行以下命令。

$ sh invoke.sh

shell 脚本中使用了 curl 标志 -v,以查看 JavaScript 修改的响应消息中的 HTTP 标头。

您可以直接提交请求,如下所示:

$ curl -v http://{org_name}-test.apigee.net/javascript-cookbook 

如果 JavaScript 正常执行,您将看到如下所示的响应:

< X-Apigee-Demo-Target: default
< X-Apigee-Demo-ApiProxyName: simple-javascript
< X-Apigee-Demo-ProxyName: default
< X-Apigee-Demo-ProxyBasePath: /javascript-cookbook
< X-Apigee-Demo-ProxyPathSuffix: /xml
< X-Apigee-Demo-ProxyUrl: http://rrt331ea.us-ea.4.apigee.com/javascript-cookbook/xml
 
{"city":"San Jose","state":"CA"}

现在,您可以修改 JavaScript 以尝试新功能,重新部署 API 代理,并通过提交相同的请求来验证结果。请务必确保您部署的 API 代理包含 JavaScript,以便使更改生效。

脚本错误

编写 JavaScript 时,您不可避免地会遇到错误。您将看到 API 代理发布的 JavaScript 错误,其格式如下所示。

{  
   "fault":{  
      "faultstring":"Execution of rewriteTargetUrl failed with error: Javascript runtime error: \"TypeError: Cannot find function getVariable in object TARGET_REQ_FLOW. (rewriteTargetUrl_js#1). at line 1 \"",
      "detail":{  
         "errorcode":"steps.javascript.ScriptExecutionFailed"
      }
   }
}

何时使用 JavaScript

在 Apigee Edge 上,通常有多种方法可以实现特定功能。尽可能使用开箱即用的政策,避免将所有 API 代理逻辑都编码为 JavaScript。虽然 Apigee Edge 利用已编译的 JavaScript 来提高性能,但 JavaScript 的性能不太可能与政策一样好。JavaScript 可能更难维护和调试。仅在需要实现独特功能时才使用 JavaScript。

如果自定义功能的性能存在问题,请尽可能使用 Java。

摘要

在本食谱主题中,您学习了如何在 API 代理配置中包含 JavaScript 以实现自定义行为。示例实现的自定义行为演示了如何获取变量、如何解析 JSON 以及如何构建自定义响应消息。