使用 JavaScript 编程 API 代理

您正在查看的是 Apigee Edge 文档。
转到 Apigee X 文档
信息

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

下载并试用示例代码

关于此食谱集示例

本实战宝典示例展示了一种 API 代理模式,在该模式下,您可以通过 JavaScript 实现 API 行为。JavaScript 示例旨在向您展示如何使用简单变量和消息内容。下面的示例展示了如何 getset 变量。第二个示例展示了如何解析 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 对象模型

准备工作

在浏览本实战宝典示例之前,您还应熟悉以下基本概念:

  • 什么是政策以及如何将它们附加到代理。如需查看有关政策的详细介绍,请参阅什么是政策?
  • 代理流的结构(如配置流中所述)。通过流,您可以指定 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>

下面是 flow 的元素的摘要。

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

将 JavaScript 代码添加到代理

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

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

试试看

如需了解如何部署和调用代理,请参阅 JavaScript 实战宝典 README

导入和部署 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 代理,并通过提交同一请求来验证结果。请务必部署包含 JavaScript 的 API 代理,以使更改生效。

脚本错误

编写 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 中,特定功能通常有多种实现方式。请尽可能使用开箱即用的政策,并避免试图使用 JavaScript 编写所有 API 代理逻辑。虽然 Apigee Edge 利用编译后的 JavaScript 来提升性能,但 JavaScript 可能无法达到政策的效果。JavaScript 可能更难以维护和调试。请保留 JavaScript,以便提供符合您需求的功能。

如果自定义功能需要考虑性能,请尽可能使用 Java。

摘要

在本实战宝典主题中,您学习了如何将 JavaScript 添加到 API 代理配置中以实现自定义行为。通过示例实现的自定义行为演示了如何获取 和变量,以及如何解析 JSON 和构建自定义响应消息。