Defining what we want to achieve
I have an API defined in API Management, and I have defined multiple APIM Products defined for this API. When a consumer sends requests to the API, I want to be able to pass some additional information to the backend.
The content of this additional information can vary depending on the APIM Product to which the consumer has subscribed. Azure APIM can determine this (based on the subscription key that is used), in what Product context the API is being called, and based on that, I can decide what additional information must be sent to the backend.
My first approach was to define a named value
in APIM for every APIM product that is defined. The name of each named value
followed a specific convention: some-value-<productid>
.
Suppose I have 2 APIM products defined with the ID’s product-a
and product-b
, I would have these named values
: some-value-product-a
, some-value-product-b
.
I then created an APIM policy that would use this named value, like this:
With that, I thought I was done. I could add an additional header to the backend request, where the value of that header would be the content of the named value
that corresponds with the product context.
Unfortunately, it is not possible to dynamically construct and use named values. I learned that named values are not evaluated at run-time when executing a policy. Instead, the named value
reference is replaced by its value when the APIM policy is saved, and therefore it is obvious that you cannot dynamically reference named value
instances.
JSON to the rescue?
To work around this, I created one single named value
that contains a JSON object, which contains a property for every defined APIM product, like this:
The idea was to retrieve and parse this named value in the set-header
policy:
However, when saving this policy the following error was given:
Error in element ‘set-header’ on line xx, column yy: Unterminated string literal. Strings that start with a quotation mark (“) must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@”) can span multiple lines.
It looks like APIM gets confused because there are quotes inside the content of the named value
.
Working around the issue using a context variable
The final solution is to make use of the set-variable
policy. For some reason, it is possible to assign the named value
that contains a JSON object to a context variable, and use that context variable inside a set-header
policy.
The final solution looks like this:
Pay attention to the fact that you need to do some string replacements before you’re able to parse the JSON contents of the named value
.
When deploying this API Management Policy via the Set-AzApiManagementPolicy
Powershell Cmdlet, be sure to specify the -Format application/vnd.ms-azure-apim.policy.raw+xml
parameter, or the validation of the policy will fail.
Hope this help — thanks for reading!
Frederik
Subscribe to our RSS feed