反模式:使用服务调出政策调用 No Target API 代理中的后端服务

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

API 代理是后端服务的代管式表层。基本 API 代理配置由 ProxyEndpoint(定义 API 代理的网址)和 TargetEndpoint(定义后端服务的网址)组成。

Apigee Edge 为基于此模式构建复杂行为提供了极大的灵活性。例如,您可以添加政策来控制 API 在将客户端请求发送到后端服务之前处理客户端请求的方式,或者在将从后端收到的响应转发到客户端之前对其进行处理。您可以使用服务调用程序政策调用其他服务,通过添加 JavaScript 代码添加自定义行为,甚至创建不调用后端服务的 API 代理。

反模式

使用服务调用程序在没有通向目标端点的路由的 API 代理中调用后端服务在技术上是可行的,但会导致有关外部服务性能的分析数据丢失。

在您不需要将请求消息转发到 TargetEndpoint 的情况下,不包含目标路由的 API 代理非常有用。ProxyEndpoint 会执行所有必要的处理。例如,ProxyEndpoint 可以通过查找 API 服务的键/值存储区来检索数据并返回响应,而不需要调用后端服务。

您可以在 API 代理中定义 null 路由,如下所示:

<RouteRule name="noroute"/>

使用 null 路由的代理是一种“无目标”代理,因为它不会调用目标后端服务。

从技术层面来讲,可以通过向无目标代理添加服务调用程序来调用外部服务,如以下示例所示:

<!-- /antipatterns/examples/service-callout-no-target-1.xml -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <FaultRules/>
    <PreFlow name="PreFlow">
        <Request>
            <Step>
                <Name>ServiceCallout-InvokeBackend</Name>
            </Step>
        </Request>
        <Response/>
    </PreFlow>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <Flows/>
    <HTTPProxyConnection>
        <BasePath>/no-target-proxy</BasePath>
        <Properties/>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="noroute"/>
</ProxyEndpoint>

但是,该代理无法提供有关外部服务行为(例如处理时间或错误率)的分析信息,因此难以评估外部服务的性能。

影响

  • 与外部服务交互的分析信息(错误代码、响应时间、目标性能等)不可用
  • 调用服务调出之前或之后所需的任何特定逻辑都包含在整体代理逻辑中,这使得它难以理解和重复使用。

最佳做法

如果 API 代理仅与单个外部服务交互,则代理应遵循基本设计模式,其中后端服务定义为 API 代理的目标端点。没有路由到目标端点的路由规则的代理不应使用 ServiceCallout 政策来调用后端服务。

以下代理配置实现的行为与上述示例相同,但遵循最佳实践:

<!-- /antipatterns/examples/service-callout-no-target-2.xml -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ProxyEndpoint name="default">
    <Description/>
    <FaultRules/>
    <PreFlow name="PreFlow">
        <Request/>
        <Response/>
    </PreFlow>
    <PostFlow name="PostFlow">
        <Request/>
        <Response/>
    </PostFlow>
    <Flows/>
    <HTTPProxyConnection>
        <BasePath>/simple-proxy-with-route-to-backend</BasePath>
        <Properties/>
        <VirtualHost>secure</VirtualHost>
    </HTTPProxyConnection>
    <RouteRule name="default">
        <TargetEndpoint>default</TargetEndpoint>
    </RouteRule>
</ProxyEndpoint>

使用服务调出来支持混搭场景,这样您可以在调用目标端点之前或之后调用外部服务。服务调出并不意味着取代目标端点调用。

更多详情