API 代理设计和开发的最佳做法

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

本文档旨在提供一系列通过 Apigee Edge 进行开发的标准和最佳实践。此处涉及的主题包括设计、编码、政策使用、监控和调试。这些信息是根据与 Apigee 合作的开发者成功实施 API 项目的经验收集的。这是一个活动文档,会不时更新。

除了此处的准则之外,您可能还会发现 Apigee Edge 反模式社区帖子对您有所帮助。

开发标准

注释和文档

  • 在 ProxyEndpoint 和 TargetEndpoint 配置中提供内嵌注释。注释增强了流的可读性,特别是在政策文件名不足以描述流的基本功能的情况下。
  • 提交有用的注释。避免显而易见的注释。
  • 使用一致的缩进、间距、垂直对齐等

框架式编码

框架式编码涉及将 API 代理资源存储在您自己的版本控制系统中,以便在本地开发环境中重复使用。例如,要重复使用某项政策,请将其存储在源代码控制系统中,以便开发者能够与其同步,并在自己的代理开发环境中使用该政策。

  • 为了实现 DRY(“不要重复自己”)原则,在可能的情况下,政策配置和脚本应实施专门的、可重复使用的功能。例如,从请求消息中提取查询参数的专用政策可以称为 ExtractVariables.ExtractRequestParameters。用于注入 CORS 标头的专用政策可以称为 AssignMessage.SetCORSHeaders。然后,这些政策可以存储在您的源代码控制系统中,并添加到需要提取参数或设置 CORS 标头的每个 API 代理中,而无需创建冗余的(因此不易管理)配置。
  • 清理 API 代理中未使用的政策和资源(JavaScript、Java、XSLT 等),尤其是那些可能会减慢导入和部署过程的大型资源。

命名规则

  • 政策 name 特性和 XML 政策文件名必须相同。
  • 脚本和 ServiceCallout 政策 name 特性和资源文件名应相同。
  • DisplayName 应向从未使用过该 API 代理的用户准确描述政策的功能。
  • 根据政策的功能为其命名。Apigee 建议您为自己的政策建立一致的命名规则。例如,使用简短前缀,后跟一系列由短划线分隔的描述性单词。例如,AM-xxx 表示 AssignMessage 政策。另请参阅 apigeelint 工具
  • 对资源文件使用适当的扩展名,对 JavaScript 使用 .js,对 Python 使用 .py,对 Java JAR 文件使用 .jar
  • 变量名称应保持一致。如果您选择一种样式(例如:camelCase 或 under_score),请在整个 API 代理中使用该样式。
  • 请尽可能使用变量前缀来根据其用途组织变量,例如 Consumer.usernameConsumer.password

API 代理开发

初始设计注意事项

  • 如需了解有关 RESTful API 设计的指导,请下载电子书 《网络 API 设计:缺失的环节》(Web API Design: The Missing Link)
  • 尽可能利用 Apigee Edge 政策和功能来构建 API 代理。避免对 JavaScript、Java 或 Python 资源中的所有代理逻辑进行编码。
  • 以有条理的方式构建流。使用多个流(每个流一个条件)比为同一个 PreFlow 和 Postflow 关联多个条件更可取。
  • 作为“故障安全机制”,使用 / 的 ProxyEndpoint BasePath 创建一个默认 API 代理。这可用于将基本 API 请求重定向到开发者网站、返回自定义响应,或者执行比返回默认 messaging.adaptors.http.flow.ApplicationNotFound 更有用的其他操作。
  • 使用 TargetServer 资源将 TargetEndpoint 配置与具体网址分离开来,从而支持跨环境的升级。
    请参阅跨后端服务器的负载平衡
  • 如果您有多个 RouteRules,请创建一个作为“default”,即没有条件的 RouteRule。确保在条件路由列表中最后定义默认 RouteRule。ProxyEndpoint 中的 RouteRule 以自上而下的顺序评估。
    请参阅 API 代理配置参考
  • API 代理软件包大小:API 代理软件包的大小不能超过 15MB。在 Apigee Edge for Private Cloud 中,您可以通过修改以下位置的 thrift_framed_transport_size_in_mb 属性来更改大小限制:cassandra.yaml(在 Cassandra 中)和 conf/apigee/management-server/repository.properties。
  • API 版本控制:如需了解 Apigee 对 API 版本控制的看法和建议,请参阅《网络 API 设计:缺失的环节》(Web API Design: The Missing Link) 电子书中的“版本控制”部分。

启用 CORS

在发布 API 之前,您需要在 API 代理上启用 CORS 以支持客户端跨源请求。

CORS(跨源资源共享)是一种标准机制,允许在网页中执行的 JavaScript XMLHttpRequest (XHR) 调用与来自非源网域的资源进行交互。CORS 是所有浏览器强制执行的同源政策一种常用解决方案。例如,如果您从浏览器执行的 JavaScript 代码向 Twitter API 发出 XHR 调用,则该调用将失败。这是因为为浏览器提供网页的网域与为 Twitter API 提供服务的网域不同。CORS 针对这个问题提供了一个解决方案,允许服务器在希望提供跨域资源共享的情况下“选择加入”。

如需了解如何在发布 API 之前在 API 代理上启用 CORS,请参阅向 API 代理添加 CORS 支持

消息负载大小

为了防止 Edge 中出现内存问题,消息载荷大小上限为 10MB。超出大小上限会导致 protocol.http.TooBigBody 错误。

该 Apigee 社区帖子中也讨论了这个问题。

以下是在 Edge 中处理大型消息大小的推荐策略:

  • 流式传输请求和响应。请注意,在您执行流式传输操作时,政策不再有权访问消息内容。请参阅流式传输请求和响应
  • 在 Edge for Private Cloud 4.15.07 及更低版本中,修改消息处理器 http.properties 文件以提高 HTTPResponse.body.buffer.limit 参数中的限制。请务必先进行测试,然后再将更改部署到生产环境。
  • 在 Edge for Private Cloud 4.16.01 及更高版本中,包含载荷的请求必须包含 Content-Length 标头,或者在流式传输的情况下,必须包含“Transfer-Encoding: chunked”标头。 对于向 API 代理发送的包含空载荷的 POST 请求,您必须传递 Content-Length 为 0。
  • 在 Edge for Private Cloud 4.16.01 及更高版本中,在 /opt/apigee/router.properties 或 message-processor.properties 中设置以下属性以更改限制。如需了解详情,请参阅在路由器或消息处理器上设置消息大小限制

    这两个属性的默认值均为“10m”,对应于 10MB:
    • conf_http_HTTPRequest.body.buffer.limit
    • conf_http_HTTPResponse.body.buffer.limit

故障处理

  • 利用 FaultRules 处理所有故障处理。(RaiseFault 政策用于停止消息流并将处理发送到 FaultRules 流。)
  • 在 FaultRules 流中,使用 AssignMessage 政策来构建故障响应,而不是使用 RaiseFault 政策。根据发生的故障类型有条件地执行 AssignMessage 政策。
  • 始终包含默认的“catch-all”故障处理程序,以便系统生成的故障可以映射到客户定义的故障响应格式。
  • 如果可能,请始终让故障响应与您的公司或项目中可用的任何标准格式匹配。
  • 使用可针对错误情况提出解决方案的、有意义且易于理解的错误消息。

请参阅处理故障

如需了解行业最佳做法,请参阅 RESTful 错误响应设计

持久性

键/值映射

  • 仅对有限的数据集使用键/值映射。它们不是为长期数据存储而设计的。
  • 在使用键/值映射时,请考虑性能,因为此信息存储在 Cassandra 数据库中。

请参阅键值映射操作政策

响应缓存

  • 如果响应失败或者请求不是 GET,请勿填充响应缓存。不应缓存创建、更新和删除。<SkipCachePopulation>response.status.code != 200 or request.verb != "GET"</SkipCachePopulation>
  • 使用一种一致的内容类型(例如 XML 或 JSON)填充缓存。检索 responseCache 条目后,使用 JSONtoXML 或 XMLToJSON 转换为所需的内容类型。这可防止存储两倍、三倍或更多的数据。
  • 请确保缓存键足以满足缓存要求。在许多情况下,request.querystring 可用作唯一标识符。
  • 除非明确要求,否则请勿在缓存键中包含 API 密钥 (client_id)。大多数情况下,对于给定请求,仅受密钥保护的 API 会向所有客户端返回相同的数据。根据 API 密钥为多个条目存储相同的值效率很低。
  • 设置适当的缓存到期间隔以避免脏读。
  • 请尽可能晚地在 ProxyEndpoint 响应 PostFlow 上执行填充缓存的响应缓存策略。换句话说,让其在平移和中介步骤之后执行,包括基于 JavaScript 的中介以及 JSON 和XML 之间的转换。通过缓存中介数据,您可以避免在每次检索缓存数据时执行中介步骤的性能成本。

    请注意,如果中介导致请求与请求之间的响应不同,您可能需要缓存未中介的数据。

  • 用于查找缓存条目的响应缓存政策应出现在 ProxyEndpoint 请求 PreFlow 中。在返回缓存条目之前,请避免实现过多逻辑,而不是缓存密钥生成。否则,缓存的优势将减至最低。
  • 通常,您应该始终让响应缓存查找尽可能靠近客户端请求。相反,您应该让响应缓存填充尽可能靠近客户端响应。
  • 在代理中使用多项不同的响应缓存政策时,请遵循以下准则,以确保每种政策的行为都是独立的:
    • 根据互斥条件执行每项政策。这有助于确保只执行多个响应缓存政策中的一个。
    • 为每个响应缓存政策定义不同的缓存资源。您可以在政策的 <CacheResource> 元素中指定缓存资源。

请参阅响应缓存政策

政策和自定义代码

政策还是自定义代码?

  • 首先(在可能的情况下)使用内置政策。Apigee 政策经过了加强、优化和支持。例如,使用标准 AssignMessage 和 ExtractVariables 政策而不是 JavaScript(如果可能)创建负载,从负载(XPath、JSONPath 等)提取信息。
  • 相较于 Python 和 Java,建议使用 JavaScript。不过,如果性能是主要要求,则应使用 Java 而非 JavaScript。

JavaScript

  • 如果 JavaScript 比 Apigee 政策更直观(例如,为许多不同的 URI 组合设置 target.url 时),请使用 JavaScript。
  • 复杂的负载解析,例如迭代 JSON 对象和 Base64 编码/解码。
  • JavaScript 政策具有时间限制,因此无限循环会被屏蔽。
  • 始终使用 JavaScript 步骤并将文件放入 jsc 资源文件夹中。JavaScript 政策类型会在部署时预编译代码。

请参阅使用 JavaScript 编程 API 代理

Java

  • 如果性能是最高优先级,或者无法在 JavaScript 中实现逻辑,请使用 Java。
  • 在源代码跟踪中收录 Java 源文件。

如需了解在 API 代理中使用 Java 的信息,请参阅使用 Java 标注将响应转换为大写Java 标注政策

Python

  • 除非绝对需要,否则请勿使用 Python。Python 脚本可能会为简单的执行带来性能瓶颈,因为它在运行时会被解释。

脚本标注(Java、JavaScript、Python)

  • 使用全局 try/catch 或等效方法。
  • 抛出有意义的异常,并正确捕获这些异常,以便在故障响应中使用。
  • 尽早抛出并捕获异常。请勿使用全局 try/catch 来处理所有异常。
  • 必要时执行 null 和未定义的检查。例如,在检索可选流变量时执行此操作。
  • 避免在脚本标注中发出 HTTP/HTTPS 请求。相反,请使用 Apigee ServiceCallout 政策,因为该政策可以很好地处理连接。

JavaScript

  • API 平台上的 JavaScript 通过 E4X 支持 XML。

请参阅 JavaScript 对象模型

Java

  • 访问消息负载时,尝试使用 context.getMessage()context.getResponseMessagecontext.getRequestMessage。这可以确保代码在请求和响应流中均可检索负载。
  • 将库导入 Apigee Edge 组织或环境,并且不将它们包含在 JAR 文件中。这可减小软件包大小,并允许其他 JAR 文件访问同一个库代码库。
  • 使用 Apigee 资源 API 导入 JAR 文件,而不是将其包含在 API 代理资源文件夹中。这将减少部署时间,并允许多个 API 代理引用相同的 JAR 文件。另一个好处是类加载器隔离。
  • 请勿使用 Java 进行资源处理(例如,创建和管理线程池)。

请参阅使用 Java 标注将响应转换为大写

Python

  • 抛出有意义的异常,并正确捕获这些异常,以便在 Apigee 故障响应中使用

请参阅 Python 脚本政策

ServiceCallouts

  • 有许多使用代理链的有效用例,您可以在一个 API 代理中使用服务标注来调用其他 API 代理。如果您使用代理链,请务必避免“无限循环”递归标注返回同一 API 代理。

    如果您要连接在同一组织和环境中的代理,请务必查看将 API 代理链接在一起,详细了解如何实现本地连接,以避免不必要的网络开销。

  • 使用 AssignMessage 政策构建 ServiceCallout 请求消息,并将请求对象填充到消息变量中。(包括设置请求负载、路径和方法。)
  • 在政策中配置的网址需要协议规范,这意味着,网址的协议部分不能通过变量指定,例如 https://。此外,您还必须对网址的网域部分和网址的其余部分使用单独的变量。例如 https://{domain}/{path}
  • 将 ServiceCallout 的响应对象存储在单独的消息变量中。然后,您可以解析消息变量并使原始消息负载保持不变,以供其他政策使用。

请参阅服务标注政策

访问实体

AccessEntity 政策

  • 为了获得更好的性能,请按 uuid(而不是应用名称)查找应用。

请参阅访问实体政策

日志

  • 在多个软件包之间和同一软件包中使用相同的 syslog 政策。这将保持一致的日志记录格式。

请参阅 MessageLogging 政策

监控

Cloud 客户无需检查 Apigee Edge 的单个组件(路由器、消息处理器等)。根据客户的健康检查请求,Apigee 的全球运营团队全面监控所有组件以及 API 健康检查。

Apigee 分析

衡量错误百分比时,分析可以提供非关键 API 监控。

请参阅 分析信息中心

Trace

API Edge 管理界面中的跟踪工具可用于在 API 的开发或生产操作期间调试运行时 API 问题。

请参阅使用跟踪工具

安全