shared flow for dynamic routing based on http header but pass existing qryparms/headers from request

@kurtkanaskie @kurtkanaskie1 @dchiesa1 

we have a requirement to set target dynamically based on incoming http header value but still copy all the other http headers & query params etc that come along with incoming request. Is there a way to build a shared flow for this functionality & utilize it at multiple api proxies so that we dont need to set target.url , copy headers, copy query parms & others manually in each api proxy that we build. what would the standard & best way to do this for multiple api proxies?

1 4 185
4 REPLIES 4

That's easy enough, just use an Assign Message in the Shared Flow to set a flow variable "target_url_set_from_header". Since this is so simple, it's hardly worth creating a Shared Flow as you just need a single Assign Message policy.

For example:

 

<AssignMessage continueOnError="false" enabled="true" name="AM-target-url">
    <AssignVariable>
        <Name>target_url_set_from_header</Name>
        <Value>https://mocktarget.apigee.net/ip</Value>
        <Ref>request.header.x-target-url</Ref>
    </AssignVariable>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

 

Then use that variable in the Target. Note that you no longer need to have a scheme when using variables for the URL, that's a recent fix.

 

    <HTTPTargetConnection>
        <URL>{target_url_set_from_header}</URL>
    </HTTPTargetConnection>

 

You could also just set "target.url" directly in the target request flow and then it won't matter what value you have in your Target Endpoint, as setting "target.url" overrides that. I like using the explicit variable as it makes it clear how the URL is being set.

You may be tempted, as was I, to just use a template value for the header for the Target URL, but that won't work as the dots in the template expression cause it to be interpreted as a hostname.

 

    <HTTPTargetConnection>
        <URL>{request.header.x-target-url}</URL>
    </HTTPTargetConnection>

 

As for copying all the headers and query params, you don't need to do anything, they are automatically copied to the target.

 

curl https://$HOST/target-in-header -H x-target-url:https://mocktarget.apigee.net/user?user=Raghu

Hello, Raghu!

 

 

 

Thank you @kurtkanaskie . But we can't see the queryparams automatically cpoied to the target.url we created using assign message  policy. Here are our assign message policy.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage continueOnError="false" enabled="true" name="AM-setTargetURL">
<DisplayName>AM-setTargetURL</DisplayName>
<Properties/>
<AssignVariable>
<Name>target.url</Name>
<Value/>
<Ref/>
<Template>http://apigee-service.{request.header.target}.bbf.com</Template>
</AssignVariable>
<Set>
<Path>{proxy.pathsuffix}</Path>
<Verb>{request.verb}</Verb>
</Set>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

And our target configuration looks like this

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TargetEndpoint name="Dynamic">
<Description/>
<FaultRules/>
<PreFlow name="PreFlow">
<Request>
<Step>
<Name>AM-setTargetURL</Name>
</Step>
</Request>
<Response/>
</PreFlow>
<PostFlow name="PostFlow">
<Request/>
<Response/>
</PostFlow>
<Flows/>
<HTTPTargetConnection>
<Properties/>
<URL>https://{target.url}</URL>
</HTTPTargetConnection>
</TargetEndpoint>

By using this we didn't see queryparams copied to target server. If you think we miss some  thing let us know.

Since you are explicitly setting the special "target.url" variable to a value, you are effectively overwriting the entire URL. Try using a different variable name (e.g. target_url_set_from_header).

This works:

curl https://$HOST/target-in-header?user=QueryParamUser \
    -H x-target-url:https://mocktarget.apigee.net/user?user=HeaderUser

Hello, HeaderUser,QueryParamUser!

 

Thank you So much @kurtkanaskie It works.