Search code examples
azurerequestpolicyapim

APIM - how to send the same request to two different backends (using the same main request body)


Azure APIM policy

i want to create an operation in an API that will post the same request to two different backends. I tried to use and set a new url, But i am having truouble in forwarding the same main request body (in json Format)

any suggestion is highly appreciated

i am usnig the following policy but i get error back as the experssion in the set-body tag this way is not allowed

<policies>
<inbound>
    <base />
    <set-variable name="bodyREQ" value="@(context.Request.Body.As<JObject>(preserveContent: true))" />
    <set-query-parameter name="code" exists-action="override">
        <value>{{FAcode}}</value>
    </set-query-parameter>
    <rewrite-uri template="/main" />
    <set-backend-service base-url="**https://mymainbackend.azurewebsites.net**" />
    <send-request mode="new" >
        <set-url>https://**mysecondaryurl.azurewebsites.net**</set-url>
        <set-method>POST</set-method>
        <set-header name="content-type" exists-action="override">
            <value>application/json</value>
        </set-header>
        <set-body>
         **@(context.Variables.GetValueOrDefault<string>("bodyREQ"))</set-body>**
        </set-body>
    </send-request>
</inbound>
<backend>
    <base />
</backend>
<outbound>
    <base />
</outbound>
<on-error>
    <base />
</on-error>

Solution

  • I fixed the following errors in the policy:

    Variable is stored as 'JObject', so the following line has to be changed to the same data type:

    context.Variables.GetValueOrDefault<string>("bodyREQ")

    =>
    context.Variables.GetValueOrDefault<JObject>("bodyREQ")

    Policy set-body: It's changed to use '{}' with return value of string:

    <set-body>@{
      return context.Variables.GetValueOrDefault<JObject>("bodyREQ").ToString();
    }
    </set-body>
    

    Complete policies:

    <policies>
        <inbound>
            <base />
            <set-variable name="bodyREQ" value="@(context.Request.Body.As<JObject>(preserveContent: true))" />
            <set-query-parameter name="code" exists-action="override">
              <value>{{FAcode}}</value>
            </set-query-parameter>
            <rewrite-uri template="/main" />
            <set-backend-service base-url="https://rfqapiservicey27itmeb4cf7q.azure-api.net/echo/200" />
            <send-request mode="new" response-variable-name="req">
                <set-url>https://rfqapiservicey27itmeb4cf7q.azure-api.net/echo/200</set-url>
                <set-method>POST</set-method>
                <set-header name="content-type" exists-action="override">
                    <value>application/json</value>
                </set-header>
                <set-body>@{
                    return context.Variables.GetValueOrDefault<JObject>("bodyREQ").ToString();
                  }
                </set-body>
            </send-request>
        </inbound>
        <backend>
            <base />
        </backend>
        <outbound>
            <base />
        </outbound>
        <on-error>
            <base />
        </on-error>
    </policies>