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. I documented it for my own reference.
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.
- http://companywebapp.azurewebsites.net/api/Profile?id={accountId}
- 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.
- <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.