As an API developer, I want to structure project related API proxies for reuse and isolation of development artifacts.
There are a few ways to achieve reuse:
In this case, I want to exploit Shared Flows via Flow Callouts. Consider a typical scenario consisting of multiple functional API areas (2 shown for brevity):
API requirements:
What's the best way to use Shared Flows, as fine grained Flow Callouts or coarse grained structures?
Solved! Go to Solution.
To support a common basepath across multiple proxies, I'm using overlapping basepaths for each proxy and a catch all for paths that don't match in the funcational proxies and in the "catch all" proxy.
Catalog Proxy:
Proxy Endpoints and flows: products Basepath = /ecommerce/v1/products Conditional Flows Catch all - non matched paths accessories Basepath = /ecommerce/v1/accessories Conditional Flows Catch all - non matched paths services Basepath = /ecommerce/v1/services Conditional Flows Catch all - non matched paths Target Endpoints default {CATALOG-TARGET-SERVER}/backend/catalog-service
Order Management Proxy:
Proxy Endpoints and flows: orders Basepath = /ecommerce/v1/orders Conditional Flows Catch all - non matched paths Target Endpoints: default {ORDER-TARGET-SERVER}/backend/order-service
Catch All Proxy (no route):
Proxy Endpoints and flows: default Basepath = /ecommerce Catch all - non matched paths
Here's one way to structure the Shared Flows, each bullet item is a Step with a Policy.
ProxyPreflow - Assumes common requirements for all endpoints in the proxy.
CatchAll - At end of conditional flows
ProxyFaultRules - Catch faults and assign error values for use in ProxyDefaultFaultRule. Uses conditional steps for each of the faults (based on this fault handling pattern).
ProxyDefaultFaultRule - Uses error variables from ProxyFaultRules steps
ProxyPostFlow - Response logging
The following Shared Flows are reusable across other proxies and also demonstrates that Shared Flows can call other Shared Flows.
CORSPreFlow
CORSPostFlow
As you can see there’s not much to the design of each API proxy, just mediating between the proxy API flows and the target APIs. The rest is done in the shared flows. Each proxy merely references the Shared Flows via Flow Callouts.
Its also easy to imagine how quickly new proxies can be developed for the project, just copy and paste the ProxyEndpoint and adjust the flows.
For error handling there is a single Fault Rule with a Flow Callout step to the ProxyFaultRules Shared Flow. Then in the DefaultFaultRule (AlwaysEnforce = true) there is a single Flow Callout step to the DefaultProxyFaultRule Shared Flow.
Benefits of this approach:
Risks of this approach:
Additional opportunities:
Here's the Proxy Endpoint for orders proxy with the Flow Callouts. Note that for the catalog proxy this structure is replicated for each of the three proxy endpoints (products, accessories, services).
<ProxyEndpoint name="default"> <Description/> <DefaultFaultRule> <AlwaysEnforce>true</AlwaysEnforce> <Step> <Name>FC-DefaultFaultRule</Name> </Step> </DefaultFaultRule> <FaultRules> <FaultRule name="Shared Fault Rules"> <Step> <Name>FC-ProxyFaultRules</Name> </Step> </FaultRule> </FaultRules> <PreFlow name="PreFlow"> <Request> <Step> <Name>FC-ProxyPreFlow</Name> </Step> <Step> <Name>KV-GetOrdersConfigValues</Name> </Step> </Request> <Response/> </PreFlow> <Flows> <-- Conditional flows removed for brevity --> <Flow name="catchAll"> <Request> <Step> <Name>FC-CatchAll</Name> </Step> </Request> <Response/> </Flow> </Flows> <PostFlow name="PostFlow"> <Request/> <Response> <Step> <Name>FC-ProxyPostFlow</Name> </Step> </Response> </PostFlow> <HTTPProxyConnection> <BasePath>/ecommerce/v1/orders</BasePath> <VirtualHost>secure</VirtualHost> </HTTPProxyConnection> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> </ProxyEndpoint>
To support a common basepath across multiple proxies, I'm using overlapping basepaths for each proxy and a catch all for paths that don't match in the funcational proxies and in the "catch all" proxy.
Catalog Proxy:
Proxy Endpoints and flows: products Basepath = /ecommerce/v1/products Conditional Flows Catch all - non matched paths accessories Basepath = /ecommerce/v1/accessories Conditional Flows Catch all - non matched paths services Basepath = /ecommerce/v1/services Conditional Flows Catch all - non matched paths Target Endpoints default {CATALOG-TARGET-SERVER}/backend/catalog-service
Order Management Proxy:
Proxy Endpoints and flows: orders Basepath = /ecommerce/v1/orders Conditional Flows Catch all - non matched paths Target Endpoints: default {ORDER-TARGET-SERVER}/backend/order-service
Catch All Proxy (no route):
Proxy Endpoints and flows: default Basepath = /ecommerce Catch all - non matched paths
Here's one way to structure the Shared Flows, each bullet item is a Step with a Policy.
ProxyPreflow - Assumes common requirements for all endpoints in the proxy.
CatchAll - At end of conditional flows
ProxyFaultRules - Catch faults and assign error values for use in ProxyDefaultFaultRule. Uses conditional steps for each of the faults (based on this fault handling pattern).
ProxyDefaultFaultRule - Uses error variables from ProxyFaultRules steps
ProxyPostFlow - Response logging
The following Shared Flows are reusable across other proxies and also demonstrates that Shared Flows can call other Shared Flows.
CORSPreFlow
CORSPostFlow
As you can see there’s not much to the design of each API proxy, just mediating between the proxy API flows and the target APIs. The rest is done in the shared flows. Each proxy merely references the Shared Flows via Flow Callouts.
Its also easy to imagine how quickly new proxies can be developed for the project, just copy and paste the ProxyEndpoint and adjust the flows.
For error handling there is a single Fault Rule with a Flow Callout step to the ProxyFaultRules Shared Flow. Then in the DefaultFaultRule (AlwaysEnforce = true) there is a single Flow Callout step to the DefaultProxyFaultRule Shared Flow.
Benefits of this approach:
Risks of this approach:
Additional opportunities:
Here's the Proxy Endpoint for orders proxy with the Flow Callouts. Note that for the catalog proxy this structure is replicated for each of the three proxy endpoints (products, accessories, services).
<ProxyEndpoint name="default"> <Description/> <DefaultFaultRule> <AlwaysEnforce>true</AlwaysEnforce> <Step> <Name>FC-DefaultFaultRule</Name> </Step> </DefaultFaultRule> <FaultRules> <FaultRule name="Shared Fault Rules"> <Step> <Name>FC-ProxyFaultRules</Name> </Step> </FaultRule> </FaultRules> <PreFlow name="PreFlow"> <Request> <Step> <Name>FC-ProxyPreFlow</Name> </Step> <Step> <Name>KV-GetOrdersConfigValues</Name> </Step> </Request> <Response/> </PreFlow> <Flows> <-- Conditional flows removed for brevity --> <Flow name="catchAll"> <Request> <Step> <Name>FC-CatchAll</Name> </Step> </Request> <Response/> </Flow> </Flows> <PostFlow name="PostFlow"> <Request/> <Response> <Step> <Name>FC-ProxyPostFlow</Name> </Step> </Response> </PostFlow> <HTTPProxyConnection> <BasePath>/ecommerce/v1/orders</BasePath> <VirtualHost>secure</VirtualHost> </HTTPProxyConnection> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> </ProxyEndpoint>
Great Answer @Kurt Kanaskie , Very well detailed one, Thank you for sharing same with community ! +1
User | Count |
---|---|
1 | |
1 | |
1 | |
1 | |
1 |