Search code examples
azure-api-managementazure-caching

Can I restrict Azure API Management cache storage by response content?


I have an OLTP API where a client can check for the status of a transaction.

Often, clients make multiple status requests for a transactions which are in a final state e.g. cancelled. I'd like to leverage Azure API Management response caching but ONLY for responses where the transaction status was final.

The API response body message is simply URL encoded e.g. reference=ABC123&status=Cancelled&amount=123.45 so determining if the transaction status is final should be simple

UPDATE

Thanks to @MohamadHaidar answer, I was able to construct a policy to achieve the caching, however the response body is now blank! I suspect this is because its being read by the condition and its only able to be read once?

<policies>
    <inbound>
        <base />
        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
        <choose>
            <when condition="@(Regex.IsMatch(context.Response.Body.As<string>(), @"status=(Cancelled|Paid)"))">
                <cache-store duration="3600" />
            </when>
        </choose>
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Solution

  • SOLUTION

    Thanks to @MohamadHaidar answer, I was able to construct my solution which I have shared below.

    NOTE: One needs to set preserveContent: true when reading the request/response body (unless you're going to set your own body after having read the existing one) otherwise it will no longer be available in the pipeline. More on that here

    So, the final solution was per below:

    <policies>
        <inbound>
            <base />
            <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" downstream-caching-type="none" />
        </inbound>
        <backend>
            <base />
        </backend>
        <outbound>
            <base />
            <choose>
                <when condition="@(Regex.IsMatch(context.Response.Body.As<string>(preserveContent: true), @"status=(Cancelled|Paid)"))">
                    <cache-store duration="3600" />
                </when>
            </choose>
        </outbound>
        <on-error>
            <base />
        </on-error>
    </policies>