Reusing APIM policy expressions - azure-api-management

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.

Related

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

Azure APIM pass through request querystring to backend completely

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" />

Azure API Management - Can I define a custom response status code?

When setting up the all the possible response codes and their descriptions for an endpoint in API Management Service, I can only choose an existing status code from a dropdown list, but it doesn't allow me to add a custom status code, such as 499. I use the 499 status code in my API for a specific type of error relevant to my applicatoin. Is there any way to add this to the list of responses?
You could dynamic mocking using APIM with an APIM policy called return-response.
<return-response>
<set-status code="200" reason="OK" />
<set-header name="content-type" exists-action="override">
<value>"application/json"</value>
</set-header>
<set-body>{
"id": "cat12345",
"name": "Garfield",
"tag": "Sleepy Cat"
}</set-body>
</return-response>
For more details, you could refer to this tutorial.
Not with forms UI. But if you select an API, there'll be a pencil in Frontend block on Design tab. It allows you to edit your API specification in OpenAPI 2/3 spec. Using that it should be possible to add a custom response statuses code.

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.

How can I create API with my custom code in Azure?

Can I create an API that has the definition of the sum of two numbers and returns me the output. I want to write all the logic in Azure Web API Management itself. Is there any provision, or do I need to create it in my machine and import it to Azure Web API Management?
Is it possible to create it in Web API in Azure itself, rather than importing it?
There are two ways to go about this. APIM does support policy expressions: https://learn.microsoft.com/en-us/azure/api-management/api-management-policy-expressions This allows you to plug in arbitrary code into request processing pipeline. You can check policy samples here: https://learn.microsoft.com/en-us/azure/api-management/policy-samples to see this in action. When combined with other policies it does allow you to a lot of things. If we assume that you "addition" operation has URI template of /add?a={a}&b={b} then you can sum up and return result with one simple policy:
<return-response>
<set-status code="200" reason="OK" />
<set-body>#{
var a = int.Parse(context.Request.Url.Query.GetValueOrDefault("a", "0"));
var b = int.Parse(context.Request.Url.Query.GetValueOrDefault("b", "0"));
return (a + b).ToString();
}</set-body>
</return-response>
As you can see this is a pretty much regular C# code, but it's limited in what you can do and what types you can use (see first link). If you can't make it work within these limitations your best bet is to move custom logic outside of APIM, into Azure Functions, for example.