Azure APIM pass through request querystring to backend completely - azure-api-management

On Azure APIM I have an operation that has querystring parameters.
In the policy I change the backend url and apply a rewrite-uri to alter the url.
Only the querystring from the caller is not applied to the backend.
Is it possible to passthrough the incoming querystring directly to the backend without changing anything?
<inbound>
<base />
<set-backend-service base-url="https://api.test.eu" />
<rewrite-uri template="dispatch/gateway/test" />
</inbound>
UPDATE
Fixed by using the folloing:
<set-backend-service base-url="https://api.test.eu" />
<rewrite-uri template="/dispatch/gateway/test" copy-unmatched-params="true" />

Related

Azure API Management - Authentication using HTTP query parameters

I want to expose an API that uses HTTP query parameters for authentication. Something like this:
{root-backendURL}/resource?login=loginName&password=loginPassword
I am using Azure API Management. I've created a new API which points to the backend service, and I've created a new operation called "Resource". For that operation I've added two Query parameters that are required.
Now I want to expose and make use of the APIM Gateway URL that should look something like this:
{root-GatewayURL}/apiName/resource
Adding those two required query parameters will make the URL look like this:
{root-GatewayURL}/apiName/resource?login=loginName&password=loginPassword
When I test the Gateway URL using Postman, I get a 401 response.
{
"code": 401,
"errors": [
{
"message": "Authentication failed."
}
]
}
I've tried to use a Send-Request policy and add from there the query parameters. This way it works.
<rewrite-uri template="/" />
<set-variable name="login" value="loginName" />
<set-variable name="password" value="loginPassword" />
<send-request mode="new" response-variable-name="resource" ignore-error="false">
<set-url>#($"{root-BackendURL}/resource?login={(string)context.Variables["login"]}&password={(string)context.Variables["password"]}")</set-url>
<set-method>GET</set-method>
</send-request>
<return-response>
<set-body>#(new JObject(new JProperty("resource",((IResponse)context.Variables["resource"]).Body.As<JObject>())).ToString())</set-body>
</return-response>
I've double checked the URLs and they are identical. Why do I get different results?
I do not want to use the policy, I want to make it work using the query parameters, because I need to use also an ID for the resource and also other query parameters, for example:
{root}/resource/{id}?limit=25&offset=50&loginName&password=loginPassword

In Azure API Management, is it possible to parameterise a Web Service URL?

Is it possible to populate the Web Service URL based off some parameter / variable that gets sent to the Base URL?
I want to be able to forward different inbound requests to API Management to different target servers, without having to create new APIs for each new server.
You can specify different backends with a policy.
There you can add your custom logic for different query values, params, headers,...
<policies>
<inbound>
<choose>
<when condition="#(context.Request.Url.Query.GetValueOrDefault("version") == "2013-05")">
<set-backend-service base-url="http://contoso.com/api/8.2/" />
</when>
<when condition="#(context.Request.Url.Query.GetValueOrDefault("version") == "2014-03")">
<set-backend-service base-url="http://contoso.com/api/9.1/" />
</when>
</choose>
<base />
</inbound>
<outbound>
<base />
</outbound>
</policies>
API Management transformation policies

How to not call backend API if cache hit with the response using azure api management policies

I'm calling the backend logic app API and storing the data in cache. Even cache hit the success , outbound policy is calling the backend API and storing the data in the cache.
Am i missing something here?
Code for policies used as below
<policies>
<inbound>
<base />
<set-variable name="input" value="#(context.Request.Headers.GetValueOrDefault("flightno",""))" />
<cache-lookup-value key="#((string)context.Variables["input"])" variable-name="flightno" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<set-variable name="ResponseResult" value="#(context.Response.Body.As<JObject>())" />
<set-variable name="Key" value="#((string)((JObject)context.Variables["ResponseResult"])["flightno"])" />
<set-variable name="payload" value="#((string)((JObject)context.Variables["ResponseResult"]).ToString())" />
<cache-store-value key="#((string)context.Variables["Key"])" value="#((string)context.Variables["payload"])" duration="60" />
</outbound>
<on-error>
<base />
</on-error>
</policies>

Parameterize Azure API Management backend

I am trying to do something like this:
<set-backend-service base-url="https://{{context.Variables['instance']}}/api" />
Or
<set-backend-service backend-id="my-{{context.Variables['instance']}}-api"/>
But getting errors that I've given an invalid URL or that APIM can't locate that backend. Is there a way to parameterize your backend?
The way you are trying is only applicable in liquid templates when using the set-body policy OR when using Named Values. In other scenarios, it has to be a policy expression.
Something like this can be done instead
<set-variable name="resource-group-name" value="rg-01" />
<set-variable name="logic-app-name" value="la-01" />
<set-backend-service id="apim-generated-policy" backend-id="#("LogicApp_" + context.Variables["resource-group-name"] + "_" + context.Variables["logic-app-name"])" />
PS: The example above is for a Logic App backend created when importing one from the Portal UI.

Reusing APIM policy expressions

I have some complex policy expressions which i want to reuse across different Operations. Is there a way to achieve this in Azure APIM?
The policy expressions can be used at different scopes such as Global, Product, API or operational scopes. To be very clear,let us say i have a utility function which is written as a policy expression. I want to reuse it in different APIs , as well as at different Operations. At the moment i need to copy the complex expression in all places where i want to use it. I want to know if there is any possibility to reuse the code.
If you're looking to define a policy once in an instance of APIM, and have it be present across all of that instance's APIs, you want to define a base policy. When you look at a policy page of a newly created API, it will look like this:
<policies>
<inbound>
<base />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
<base /> refers to whatever inbound/backend/outbound/on-error policies are defined for All APIs. To get to that policy document, see the image below
The policies you define there are imported by the <base /> tag in all your APIs.
Using Named Values may also facilitate code reuse.