1
votes

We are using Azure API Management to publish, monitor and maintain APIs. Also we have implemented B2C login for Authentication and Authorization.

I'm trying to configure external cache for APIs. Somehow caching policy is not working. I refer following link https://docs.microsoft.com/en-us/azure/api-management/api-management-sample-cache-by-key

Based on logged in user tenant id, we want to store the template in cache and retrieve later for next request. Here is the policy I have written.

<policies>
    <inbound>
        <set-variable name="tenantId" value="@(context.Request.Headers.GetValueOrDefault("Authorization","").Split(' ')[1].AsJwt()?.Subject)" />
        <cache-lookup-value key="@("templates-" + context.Variables["tenantId"])" variable-name="templates" />
        <choose>
            <when condition="@(!context.Variables.ContainsKey("tenantId"))">
                <send-request mode="new" response-variable-name="templateResponse" timeout="15" ignore-error="true">
                    <set-url>https://abc.azure-api.net/api/notification/templates/?api-version=v1</set-url>
                    <set-method>GET</set-method>
                </send-request>
                <set-variable name="templates" value="@(((IResponse)context.Variables["templateResponse"]).Body.As<string>())" />
                <cache-store-value key="@("templates-" + context.Variables["tenantId"])" value="@((string)context.Variables["templates"])" duration="10000" />
            </when>
        </choose>
        <base />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
2

2 Answers

0
votes

As long as there is an authorization header with the request then APIM will not cache the request unless you enable the private response caching.

You can set the allow-private-response-caching attribute to ture in order to enable private response caching https://docs.microsoft.com/en-us/azure/api-management/api-management-caching-policies#elements.

if with that it does not continue to work then I recommend file a support ticket to the MS team.

0
votes

I made some mistake while writing policy. Here is the corrected policy.

<policies>
<inbound>
    <set-variable name="userId" value="@(context.Request.Headers.GetValueOrDefault("Authorization","").Split(' ')[1].AsJwt()?.Subject)" />
    <cache-lookup-value key="@("templates-" + context.Variables["userId"])" variable-name="templates" caching-type="external" />
    <choose>
        <when condition="@(!context.Variables.ContainsKey("templates"))">
            <send-request mode="new" response-variable-name="templateResponse" timeout="15" ignore-error="true">
                <set-url>https://appname.azurewebsites.net/api/templates</set-url>
                <set-method>GET</set-method>
                <set-header name="Authorization" exists-action="override">
                    <value>@(context.Request.Headers.GetValueOrDefault("Authorization",""))</value>
                </set-header>
            </send-request>
            <set-variable name="templates" value="@(((IResponse)context.Variables["templateResponse"]).Body.As<string>())" />
            <cache-store-value key="@("templates-" + context.Variables["userId"])" value="@((string)context.Variables["templates"])" duration="10000" />
        </when>
    </choose>
    <base />
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <set-body>@((string)context.Variables["templates"])</set-body>
    <base />
</outbound>
<on-error>
    <base />
</on-error>