Just adding up little flow & can work with you if you face any issues but it is mostly easy to implement..
- Proxy Pre-Flow:
Step 0 (optional - follow your existing security policies flow)
- Shared flow - you may want to enable basic security guard rails (enable few regex,rate limiting etc) with in the shared flow
https://cloud.google.com/apigee/docs/api-platform/reference/policies/reference-overview-policy
Step 1 - Shared flow which does verify of access token (assuming you have oauth enabled) & throw error if it is invalid
Sample verification
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 async="false" continueOnError="false" enabled="true" name="OA-VerifyAccessToken">
<DisplayName>OA-VerifyAccessToken</DisplayName>
<Properties/>
<Attributes/>
<ExternalAuthorization>false</ExternalAuthorization>
<Operation>VerifyAccessToken</Operation>
<SupportedGrantTypes/>
<GenerateResponse enabled="true"/>
<Tokens/>
</OAuthV2>
Step -2 - Remove the header which you don’t want to propagate further using Assign Message as it is not required..
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-RemoveHeaders">
<DisplayName>AM-RemoveHeaders</DisplayName>
<Properties/>
<Remove>
<Headers>
<Header name="Authorization"/>
</Headers>
</Remove>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
Step 3 - You can have standard conditional flow to forward the req (eg: GET/POST what ever is the functionality)
Step 4 - Now add the backend related calls/caching mechanism with in PostFlow ( the proxy endpoint PostFlow executes before the target endpoint PreFlow). It looks simple,clean and no duplicate on different conditional flow..
https://cloud.google.com/apigee/docs/api-platform/cache/persistence-tools
in Apigee X, the named caches get implicitly created at runtime when you reference one within a cache policy..
Proxy PostFlow:
First do the lookup in cache for a token
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<LookupCache async="false" continueOnError="false" enabled="true" name="LC-Sample">
<DisplayName>LC-Sample</DisplayName>
<CacheResource>Sample</CacheResource>
<AssignTo>access_token</AssignTo>
<Scope>Exclusive</Scope>
<CacheKey>
<KeyFragment>access_token</KeyFragment>
</CacheKey>
</LookupCache>
Next perform service callout on below condition (make sure you are reading the variables from kvm in pre-flow itself after step 0 - didn’t add it and assuming you know how to read the encrypted kvm values) .
Also make sure you setup the required setup for ssl -
https://cloud.google.com/apigee/docs/api-platform/reference/policies/service-callout-policy#sslinfo
lookupcache.LC-Sample.cachehit = false
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ServiceCallout async="false" continueOnError="false" enabled="true" name="SC-Sample">
<DisplayName>SC-Sample</DisplayName>
<Properties/>
<Request clearPayload="true" variable="sampleRequest">
<Set>
<FormParams>
<FormParam name="grant_type">{private.sample_grant_type}</FormParam>
<FormParam name="client_id">{private.sample_client_id}</FormParam>
<FormParam name="client_secret">{private.sample_client_secret}</FormParam>
</FormParams>
<Headers>
<Header name="Content-Type">application/x-www-form-urlencoded</Header>
</Headers>
<Verb>POST</Verb>
</Set>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request>
<Response>sampleResponse</Response>
<HTTPTargetConnection>
<Properties/>
<URL>https://{private.sample_tokenUrl}</URL>
<SSLInfo>
<Enabled>true</Enabled>
<ClientAuthEnabled>true</ClientAuthEnabled>
<KeyStore>{var-for-keystore}</KeyStore>
<KeyAlias>{var-for-keyalias}</KeyAlias>
<TrustStore>{var-for-truststore}</TrustStore>
<IgnoreValidationErrors>false</IgnoreValidationErrors>
</SSLInfo>
</HTTPTargetConnection>
</ServiceCallout>
Now extract the response from the service callout using below condition
lookupcache.LC-Sample.cachehit = false and sampleResponse.content != null
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-Sample">
<DisplayName>EV-Sample</DisplayName>
<Properties/>
<JSONPayload>
<Variable name="access_token">
<JSONPath>$.access_token</JSONPath>
</Variable>
</JSONPayload>
<Source clearPayload="false">sampleResponse.content</Source>
</ExtractVariables>
Now you populate the token using below condition
lookupcache.LC-Sample.cachehit = false
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PopulateCache async="false" continueOnError="false" enabled="true" name="PC-Sample">
<DisplayName>PC-Sample</DisplayName>
<CacheResource>Sample</CacheResource>
<Source>access_token</Source>
<Scope>Exclusive</Scope>
<CacheKey>
<KeyFragment>access_token</KeyFragment>
</CacheKey>
<ExpirySettings>
<TimeoutInSeconds ref="private.sampleTimeOut">12345</TimeoutInSec>
</ExpirySettings>
</PopulateCache>
Step 5 - Final assign target url & access token in Target PreFlow
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-SampleTarget">
<DisplayName>AM-SampleTarget</DisplayName>
<Properties/>
<AssignVariable>
<Name>target.url</Name>
<Template>https://{private.sample_targetUrl}</Template>
</AssignVariable>
<Set>
<Headers>
<Header name="Authorization">Bearer {access_token}</Header>
</Headers>
</Set>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>
Error handling & logging follow your standard process..
Good Luck.