/ Üllar Seerme

To read named values and context at the same time in Azure APIM policies

January 5, 2022

While needing to set up the reading of secrets from Key Vault using API Management, I had to read both the stored named values and a query parameter from a request sent to an API. I’ve previously only had to either use only named values:

1
2
3
4
5
6
7
8
9
<policies>
    <inbound>
        <return-response>
            ...
            <set-body>{{named-value}}</set-body>
        </return-response>
    </inbound>
    ...
</policies>

Or work with simpler expressions:

1
2
3
4
5
6
<policies>
    <inbound>
        <set-variable name="callback_url" value="@(context.Request.Headers.GetValueOrDefault("Callback-Url","placeholder"))" />
    </inbound>
    ...
</policies>

But never to combine the two and I found it surprisingly difficult to find examples of both being leveraged. Only thanks to this Stack Overflow answer did I finally come upon the correct invocation:

1
2
3
4
5
6
7
8
9
<policies>
    <inbound>
        <send-request mode="new" response-variable-name="response" timeout="20" ignore-error="false">
            <set-url>@($"https://{{vault-name}}.vault.azure.net/secrets/{context.Request.OriginalUrl.Query.GetValueOrDefault("secretName")}?api-version=7.2")</set-url>
            ...
        </send-request>
    </inbound>
    ...
</policies>

This could also leverage a previously set variable if the use case calls for it:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<policies>
    <inbound>
        <set-variable name="secret-name" value="@(context.Request.OriginalUrl.Query.GetValueOrDefault("secretName"))" />
        <send-request mode="new" response-variable-name="response" timeout="20" ignore-error="false">
            <set-url>@($"https://{{vault-name}}.vault.azure.net/secrets/{(string)context.Variables["secret-name"]}?api-version=7.2")</set-url>
            ...
        </send-request>
    </inbound>
    ...
</policies>

I find that syntax to be just horrible, so here’s to hoping this can save others some time in trying to find the right way to go about this when the official documentation is scarce1.


  1. I only found one bit in the official documentation and that was completely tangential to the problem at hand. It was also missing the crucial bit of using named values as well. ↩︎

Page history