Sometimes our backends return 3xx redirect responses that are relative to the application itself, not the API proxy we have deploy in Apigee. In these cases, we must prepend the basepath to the Location header.
As an example, we can create an API proxy in front of https://httpbin.org/status/302 with a basepath of /my-redirect-test/v1 - which returns this response...
< HTTP/1.1 302 FOUND < Date: Thu, 08 Apr 2021 12:47:15 GMT < Content-Length: 0 < Connection: keep-alive < Server: gunicorn/19.9.0 < location: /redirect/1 < Access-Control-Allow-Origin: * < Access-Control-Allow-Credentials: true
It is redirecting to /redirect/1 which doesnt exist. We want to include the basepath and redirect to /my-redirect-test/v1 .
We can do this using an Assign Message policies below:
apiproxy/policies/AssignRedirectBasePath.xml
<AssignMessage name="AssignRedirectRewrite"> <Set> <Headers> <Header name="Location">{proxy.basepath}{response.header.location}</Header> </Headers> </Set> <AssignTo createNew="false" transport="http" type="response"/> </AssignMessage>
... and attach it anywhere in the Response flow with a condition to ensure it is only run for 3xx responses.
For example:
apiproxy/proxies/default.xml
<ProxyEndpoint name="default"> <PreFlow name="PreFlow"> <!-- omitted... --> <Response> <!-- omitted... --> <Step> <Name>AssignRedirectRewrite</Name> <Condition>response.status.code =| "3"</Condition> </Step> </Response> </PreFlow> <HTTPProxyConnection> <BasePath>/my-redirect-test/v1</BasePath> <VirtualHost>secure</VirtualHost> </HTTPProxyConnection> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> </ProxyEndpoint>
Nice!
And.... what if the response header includes a fully-qualified URL? Any suggestions for that?