I'm trying to create a request with parameters in Azure API Management.
I have the following API(returns all invoices):
www.apibackend.com/invoice
This API can also handle parameters like this(returns invoice with ID 1):
www.apibackend.com/invoice/1
In my APIM service I've got the following code:
<policies>
<inbound>
<base />
<set-backend-service base-url="www.apibackend.com/" />
<rewrite-uri template="/invoice" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
With the APIM URL(for example: www.apim.com/test/GetInvoices) I can make the following request to my backend:
www.apibackend.com/invoice
This will return all the invoices, but how do I only retrieve the invoice with ID 1? If i make the request "www.apim.com/test/GetInvoices/1" I will get an error.
Hope someone can help!
In APIM change your Operation template to GetInvoices/{id} then in policies you'll be able to do:
<rewrite-uri template="/invoice/{id}" />
Related
I am trying to do URL based routing for my APIs but I am not able to achieve as my API endpoints contain a wildcard in the middle of the URL, like:
/prodapi/v1.0/{appId}/level
/prodapi/v1.0/{appId}/products
appId is my customers white label ID, so it's unique for all our customers.
So far I have tried :
Azure application gateway [ But you can only handle at the end of your URL]
Azure Fron door [Have the same settings]
API management [ Not allowing me to do wildcard]
Can someone help me with any azure native or Out of the box solution.
If you want to route the traffic depending on a specific path parameter, you could use Api management service and write a inbound policy as such:
<policies>
<inbound>
<base />
<set-variable name="appId" value="#(context.Request.MatchedParameters["appId"])" />
<choose>
<when condition="#(int.Parse(context.Variables.GetValueOrDefault<string>("appId")) == 1)">
<set-backend-service base-url="https://google.com/" />
</when>
<when condition="#(int.Parse(context.Variables.GetValueOrDefault<string>("appId")) == 2)">
<set-backend-service base-url="https://twitter.com/" />
</when>
<otherwise>
<set-backend-service base-url="https://facebook.com/" />
</otherwise>
</choose>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Replacing the backend-service with your prefer url ofc :)
API management is very powerful, so I'm sure that you'll find the solution there if this is not what you were looking for.
How do I specify a policy so that Azure API Management creates a different response cache for each combination of query parameters?
Suppose I have an endpoint /my-endpoint that takes 2 query parameters (item_id and language).
I want API Management to make a different cache for each combination of my query parameter values.
For example, I want the following requests to store different cache values for the responses:
/my-endpoint?item_id=4&language=en
/my-endpoint?item_id=4&language=nl
/my-endpoint?item_id=2&language=en
/my-endpoint?item_itd=2&language=nl
How do I do this?
In particular, do both of the following APIM policies (APIM Policy 1 and APIM Policy 2) work? Or is there a difference in how Azure API Management response caching works when I use a single tag with values separated by commas (see APIM Policy 1), or when I use multiple tags, each with a different value (see APIM Policy 2)?
APIM Policy 1
<policies>
<inbound>
<base />
<cache-lookup vary-by-developer="false" vary-by-developer-groups="false" allow-private-response-caching="false" must-revalidate="false" downstream-caching-type="none">
<vary-by-query-parameter>item_id;language</vary-by-query-parameter>
</cache-lookup>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<cache-store duration="3600" />
</outbound>
<on-error>
<base />
</on-error>
</policies>
APIM Policy 2
<policies>
<inbound>
<base />
<cache-lookup vary-by-developer="false" vary-by-developer-groups="false" allow-private-response-caching="false" must-revalidate="false" downstream-caching-type="none">
<vary-by-query-parameter>item_id</vary-by-query-parameter>
<vary-by-query-parameter>language</vary-by-query-parameter>
</cache-lookup>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
<cache-store duration="3600" />
</outbound>
<on-error>
<base />
</on-error>
</policies>
If you don't get the "vary-by-query-parameter" to work, you could do something like this:
<cache-store-value key="#("my-variable-" + context.Request.MatchedParameters.GetValueOrDefault("item_id","")) + "-" + context.Request.MatchedParameters.GetValueOrDefault("language",""))" value="#(context.Response.Body.As<String>(true))" duration="3600" />
In this way you combine your parameters to get unique cache variabel names.
Given your case above you will have 4 different cache variables:
my-variable-4-en
my-variable-4-nl
my-variable-2-en
my-variable-2-nl
They will all contain different response bodies.
I am wondering whether it is possible to specify something like Named value but for each API separately?
So if I have, say foo-API and bar-API I can specify for each a named value-like variable, eg my-url. So now when I create a global policy
<policies>
<inbound>
<base />
<send-request mode="new">
<set-url>{{my-url}}</set-url>
<set-method>POST</set-method>
<set-body>something</set-body>
</send-request>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
but send-request will send request to the API specific URL (eg. different URL for DEV, TEST, PROD)
Not possible. Named values are a global collection, the only workaround is to name them to be descriptive enough, i.e. prefix with API id.
I am trying to set the policy for service fabric but I get the following error
One or more fields contain incorrect values: Error in element
'set-backend-service' on line 16, column 10: Backend with id
'servicefabric' could not be found.
Where do i set the backend id
<policies>
<inbound>
<base />
<set-backend-service backend-id="servicefabric" sf-service-instance-name="fabric:/Medivet.MicroServices/Medivet.WebApi" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
There is still no UI to manage backends. Will have to use API: https://learn.microsoft.com/en-us/rest/api/apimanagement/2019-01-01/backend
I am trying to deal with an Backend API(REST) with no swagger documents to be accessed through Azure APIM.
I want all the calls directed to the Backend API with me not manually creating GET/PUT/POST for all the resources. My inbound policies for all operations is below
'
<policies>
<inbound>
<set-variable name="requestPath" value="#(context.Request.Url.Path)" />
<base/>
<set-backend-service base-url="https://*****/****/" />
<rewrite-uri template="#(context.Request.Url.Path)" copy-unmatched-params="true" />
</inbound>
<backend>
<base/>
</backend>
<outbound>
<base/>
</outbound>
</policies>
`
However when hit the APIM i was given
{
"statusCode": 404,
"message": "Resource not found"
}
Any help is appreciated Thanks
The easy way to do this is to create one operation for each HTTP method you support and use /* for the template. This will match any inbound path/query and forward it to the backend.