Blog Post

Healthcare and Life Sciences Blog
5 MIN READ

Azure API Management with Call Chain of Backend APIs

Yan_Liang's avatar
Yan_Liang
Icon for Microsoft rankMicrosoft
Mar 23, 2025

There are scenarios where an application needs to call multiple back-end services in a chain. Each sequential call uses the result from the previous call as input. By using Azure API Management Service, we can achieve this.

The backend can be rest api or soap api.

 

The call scenario:

 

 

We can integrate APIs to Azure API Management services and  implement policies in API Manager to achieve this goal.  Please refer to Policies

 

Step 1

First, we need to identify what APIs are required to aggregate and their input parameters. In my case, I had two APIs; one gives profile details and the other one fetches the user tasks of that user. 

  1. http://companywebapp.azurewebsites.net/api/Profile?id={accountId}  
  2. http://companyebapp.azurewebsites.net/api/Task?id={accountId}  

The common input parameter for both APIs is accountId.

Step 2

Create a new operation with name Dashboard as Get request with query parameter accountId and save. 

 

 

Step 3

Open the policy editor for Dashboard operation by clicking Inbound Processing-->Code view.

We need to create a variable with name accountId like below. We can use this variable to pass the value into the APIs.

  1. <set-variable name="accountId" value="@(context.Request.Url.Query["accountId"].Last())" />  

Step 4

Create a send-request policy for API1 and API2 which fetches profile details and profile tasks. The response-variable-name stores the response from the API. On set-url, we use the API to hit, which we want to fetch data from and stores the response to response-variable-name we declared. In set-method, we specify the HttpVerb based on the request we made. If we want to pass any values in the header we pass in set-header value.

<send-request mode="new" response-variable-name="profiledetails" timeout="20" ignore-error="true">  

            <set-url>@($"http://companywebapp.azurewebsites.net/api/Profile?id={(string)context.Variables["accountId"]}")</set-url>  

            <set-method>GET</set-method>  

            <set-header name="Content-Type" exists-action="override">  

                <value>application/x-www-form-urlencoded</value>  

            </set-header>>  

        </send-request>  

<send-request mode="new" response-variable-name="taskdetails" timeout="20" ignore-error="true">  

            <set-url>@($"http://companywebapp.azurewebsites.net/api/Task?id={(string)context.Variables["accountId"]}")</set-url>  

            <set-method>GET</set-method>  

            <set-header name="Content-Type" exists-action="override">  

                <value>application/x-www-form-urlencoded</value>  

            </set-header>  

        </send-request>  

Step 5

We need to collect the response from the two APIs and use return-response policy to send the data. In return-reponse policy we need to aggregate the responses in set-body policy. In the previous step we collected the response and stored in profiledetails and taskdetails.

This part is the final response, on set-body we are casting the response to JSON object and aggregating the two API response.

<return-response>  

            <set-status code="200" reason="OK" />  

            <set-header name="Content-Type" exists-action="override">  

                <value>application/json</value>  

            </set-header>  

            <set-body>@(new JObject(new JProperty("profiledetails",((IResponse)context.Variables["profiledetails"]).Body.As<JObject>()),  

                            new JProperty("taskdetails",((IResponse)context.Variables["taskdetails"]).Body.As<JObject>())  

                            ).ToString())</set-body>  

        </return-response>  

Summary

By following these simple steps, we can aggregate two API's responses and send a single collective response. The example is very simple but in a real-time scenario, you may encounter multiple APIs with a lot of input parameters.

Sometimes, we need to pass the Authorization token to every API request header or in a scenario based on one API response we need to call different APIs all we can achieve with API Manager.

Below is the code containing the complete policy with the Authorization Token.


<policies>  

    <inbound>  

        <base />  

        <set-variable name="accountId" value="@(context.Request.Url.Query["accountId"].Last())" />  

        <set-variable name="token" value="@(context.Request.Headers.GetValueOrDefault("Authorization","scheme param"))" />  

        <send-request mode="new" response-variable-name="profiledetails" timeout="20" ignore-error="true">  

            <set-url>@($"http://companywebapp.azurewebsites.net/api/Profile?id={(string)context.Variables["accountId"]}")</set-url>  

            <set-method>GET</set-method>  

            <set-header name="Content-Type" exists-action="override">  

                <value>application/x-www-form-urlencoded</value>  

            </set-header>  

            <set-header name="Authorization" exists-action="override">  

                <value>@($"{(string)context.Variables["token"]}")</value>  

            </set-header>  

        </send-request>  

        <send-request mode="new" response-variable-name="taskdetails" timeout="20" ignore-error="true">  

            <set-url>@($"http://companywebapp.azurewebsites.net/api/Task?id={(string)context.Variables["accountId"]}")</set-url>  

            <set-method>GET</set-method>  

            <set-header name="Content-Type" exists-action="override">  

                <value>application/x-www-form-urlencoded</value>  

            </set-header>  

            <set-header name="Authorization" exists-action="override">  

                <value>@($"{(string)context.Variables["token"]}")</value>  

            </set-header>  

        </send-request>  

        <return-response>  

            <set-status code="200" reason="OK" />  

            <set-header name="Content-Type" exists-action="override">  

                <value>application/json</value>  

            </set-header>  

            <set-body>@(new JObject(new JProperty("profiledetails",((IResponse)context.Variables["profiledetails"]).Body.As<JObject>()),  

                            new JProperty("taskdetails",((IResponse)context.Variables["taskdetails"]).Body.As<JObject>())  

                            ).ToString())</set-body>  

        </return-response>  

        <cache-lookup vary-by-developer="false" vary-by-developer-groups="false" allow-private-response-caching="true" downstream-caching-type="none">  

            <vary-by-header>Accept</vary-by-header>  

            <vary-by-header>Accept-Charset</vary-by-header>  

        </cache-lookup>  

    </inbound>  

    <backend>  

        <base />  

    </backend>  

    <outbound>  

        <base />  

        <cache-store duration="3600" />  

    </outbound>  

    <on-error>  

        <base />  

    </on-error>  

</policies>  

 

Published Mar 23, 2025
Version 1.0
No CommentsBe the first to comment