@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?
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.
User | Count |
---|---|
1 | |
1 | |
1 | |
1 | |
1 |