How to merge two variables into one in a response? [duplicate]
Asked Answered
W

2

0

I have two APIs added to Azure API Management. It's basically the same API, but for different environments. For monitoring purposes, I want to create an operation that would call the same method in both of the APIs and merge their result into one. I currently work on mocked APIs with mocked data.

To achieve that I created a blank API with a blank operation. Inside this operation, I declared the following inbound policies:

<inbound>
    <set-variable name="env1" value="" />
    <set-variable name="env2" value="" />
    <send-request mode="new" response-variable-name="env1" timeout="20" ignore-error="false">
        <set-url>https://env1-api.azure-api.net/api/data</set-url>
        <set-method>GET</set-method>
        <set-header name="Content-Type" exists-action="override">
            <value>application/json</value>
        </set-header>
    </send-request>
    <send-request mode="new" response-variable-name="env2" timeout="20" ignore-error="false">
        <set-url>https://env2-api.azure-api.net/api/data</set-url>
        <set-method>GET</set-method>
        <set-header name="Content-Type" exists-action="override">
            <value>application/json</value>
        </set-header>
    </send-request>
    <base />
</inbound>

When tested the operation called throws 500 (which, I believe, is understandable, as no response is being set). When I look at the Trace tab I can see two messages:

GET request to 'https://env1-api.azure-api.net/api/data' has been sent, result stored in 'env1' variable.

GET request to 'https://env2-api.azure-api.net/api/data' has been sent, result stored in 'env2' variable.

Based on that I conclude that the calls are working correctly. Here's where I'm stuck. I don't know how to merge those two variables inside a response.

The API's return an array of objects in the form of a JSON object. What I want to achieve is to merge those two responses into one response that will be returned by the operation. How can I compose a response?

Please have in mind that I'm a noob in Azure, so my approach might be too primitive. If you have something better I'd love to hear about it.

Witchcraft answered 24/9, 2019 at 13:50 Comment(0)
P
1

To add to Aleksander's answer, inside the return-response policy, there are two ways you can compose the final body

  1. Using policy expressions
<set-body>@{
    var output = new
    {
        success = true,
        var1 = context.Variables["var1"]
    };
    return JsonConvert.SerializeObject(output);
}</set-body>
  1. Use liquid templates
<set-variable name="var1body" value="@((IResponse)context.Variables["var1"]).Body.As<string>())" />
<set-body template="liquid">{
"success": true,
"var1": "{{context.Variables["var1body"]}}"
}</set-body>

You can read more about the set-body policy in its doc.

Primero answered 27/9, 2019 at 7:8 Comment(2)
This answer lacked only parsing of IResponse :-) <set-variable name="var1body" value="@((IResponse)context.Variables["var1"]).Body.As<string>())" /> If you would add it, I would accept it as an answer.Witchcraft
Added that. Thanks!Primero
C
2

Take a look at return-response policy: https://learn.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#ReturnResponse

Under set-body, you can merge those two strings.

Copilot answered 24/9, 2019 at 14:23 Comment(2)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.Robbi
Hi, Aleksandar! Although I noticed "return response" before I kind of did not use it, perhaps because the "aborts pipeline execution" sounded kind of like not the thing I wanted to use. I will try that, but still not sure how to compose to the body.Witchcraft
P
1

To add to Aleksander's answer, inside the return-response policy, there are two ways you can compose the final body

  1. Using policy expressions
<set-body>@{
    var output = new
    {
        success = true,
        var1 = context.Variables["var1"]
    };
    return JsonConvert.SerializeObject(output);
}</set-body>
  1. Use liquid templates
<set-variable name="var1body" value="@((IResponse)context.Variables["var1"]).Body.As<string>())" />
<set-body template="liquid">{
"success": true,
"var1": "{{context.Variables["var1body"]}}"
}</set-body>

You can read more about the set-body policy in its doc.

Primero answered 27/9, 2019 at 7:8 Comment(2)
This answer lacked only parsing of IResponse :-) <set-variable name="var1body" value="@((IResponse)context.Variables["var1"]).Body.As<string>())" /> If you would add it, I would accept it as an answer.Witchcraft
Added that. Thanks!Primero

© 2022 - 2024 — McMap. All rights reserved.