APIM- Empty original request body in send-request

Greg Smith 15 Reputation points
2023-02-01T19:29:54.4166667+00:00

I have an inbound policy where I need to take a list of strings from the request body and send a request to another API to get some additional data:


    <inbound>
        <base />
        <send-request mode="copy" response-variable-name="varCCs">
            <set-url>...</set-url>
            <set-method>POST</set-method>
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-body template="liquid">
            [
                {%JSONArrayFor item in body.ccUsers %}
                "{{item}}"
                {% endJSONArrayFor %}
            ]
            </set-body>
        </send-request>
    </inbound>

However, in my for loop inside the set-body, the body and all its fields are empty. I thought changing the send-request mode from new to copy would fix this, but that doesn't seem to be the case. Does anyone know why this is or if there is a workaround?

Azure API Management
Azure API Management
An Azure service that provides a hybrid, multi-cloud management platform for APIs.
2,091 questions
{count} votes

1 answer

Sort by: Most helpful
  1. MuthuKumaranMurugaachari-MSFT 22,311 Reputation points
    2023-03-01T15:34:15.68+00:00

    Greg Smith We are very sorry for the delayed response. I am able to confirm that even with "copy" mode in send-request policy, APIM won't the copy the body of the original request and hence the input will be null with the liquid template above.

    The workaround is to create a variable with required values from the request body and use it in the liquid template as shown below (based on sample policy snippet: https://github.com/Azure/api-management-policy-snippets/blob/master/examples/Extracting%20multiple%20values%20from%20xml%20documents.policy.xml):

    <inbound>
            <base />
            <set-variable name="jsonBody" value="@{
                var bodyObj = context.Request.Body.As<JObject>(preserveContent:true);
                var obj = new JObject();
                obj["ccUsers"] = (JArray)bodyObj["ccUsers"];            
                return obj;
            }" />
            <send-request mode="copy" response-variable-name="varCCs">
                <set-url>http://contoso.com</set-url>
                <set-method>POST</set-method>
                <set-header name="Content-Type" exists-action="override">
                    <value>application/json</value>
                </set-header>
                <set-body template="liquid">  
                {% assign vars = context.Variables["jsonBody"] %}   
                [{%JSONArrayFor item in vars["ccUsers"] %}"{{item}}"{% endJSONArrayFor %}]
                </set-body>
            </send-request>
        </inbound>
    
    

    We will add a note to our doc to specify this limitation and if you have feedback regarding this feature, please submit it via https://aka.ms/apimwish and others can upvote your feature too. This will help our product team prioritize the features.

    I hope this helps with your question and let me know if you have any questions. I would be happy to answer any.


    If you found the answer to your question helpful, please take a moment to mark it as "Yes" for others to benefit from your experience.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.