Use API-M To Mask Async APIs When Moving Implementation to Logic Apps/Functions
I recently talked to a customer who is in the process of moving API implementation to Logic Apps (with request trigger and response action).
The Logic App act as an Azure Function orchestrator, connecting them together and pass data along from one to the other. A single run usually complete within 2 minutes, however, if the Function App went cold it may take more than 2 minutes.
Here's a mock Logic App to simulate this scenario, notice the 150 seconds delay.
Logic Apps has a 120-second request timeout, as documented here, so if the run last more than 2 minutes, the connection will be closed and respond will not be available to the caller.
The recommended approach is to enable "Async response" on the settings page of the response action, in which the Logic App will return 202 with a location header immediately, and the caller can check the location url until the run reaches its terminal state.
However, this would require updating the client (caller) to follow location header on 202, which is not possible in this case.
API Management came to the rescue.
With API Management policy, it could allow us to enable "Async response" in Logic Apps, yet expose (or in other word, mask) the request trigger as if it's a synchronous call.
<outbound>
<base />
<retry condition="@(((IResponse)context.Variables["var"]).StatusCode == 202)" count="10" interval="30">
<send-request mode="new" response-variable-name="var" ignore-error="false">
<set-url>@(context.Response.Headers["location"][0])</set-url>
<set-method>GET</set-method>
</send-request>
</retry>
<return-response response-variable-name="var" />
</outbound>
Above outbound policy will keep retry the url specified in header "location" at a pre-defined interval (30 seconds in my case), and only return the terminal payload to the caller. And calling the API-M endpoint appears as a synchronous call.