您正在查看 Apigee 和 Apigee Hybrid 文档。
查看 Apigee Edge 文档。
API 代理是后端服务的代管式表层。基本 API 代理配置包含 ProxyEndpoint(定义 API 代理的网址)和 TargetEndpoint(用于定义后端服务的网址)。
Apigee 提供极大的灵活性,让您能够基于此模式构建复杂的行为。例如,您可以添加政策来控制 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>
使用服务调出来支持混搭场景,这样您可以在调用目标端点之前或之后调用外部服务。服务调出并不意味着取代目标端点调用。