How do I transform the response of my api using set-body policies in apim

Diogo Capitao 0 Reputation points
2023-02-22T15:33:11.4933333+00:00

I was using these sets of policies in the Demo Conference Api, but im unable to extract only certain properties using the set-body policy.


<policies>
	<inbound>
        <base />
        <set-header name="Accept-Encoding" exists-action="override">
            <value>deflate</value>
        </set-header>
	</inbound>
	<backend>
		<base />
	</backend>
	<outbound>
        <return-response>
            <set-status code="200" reason="Success" />
            <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-body>@{
        var response = context.Response.Body.As<string>();
        return response.ToString();
    }</set-body>
        </return-response>
	</outbound>
	<on-error>
		<base />
	</on-error>
</policies>

How can I proceed in order to extract for example the version in the response below?



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

1 answer

Sort by: Most helpful
  1. MuthuKumaranMurugaachari-MSFT 22,416 Reputation points
    2023-02-23T16:11:41.9366667+00:00

    Diogo Capitao Use liquid template with set-body policy to transform the response body (or request body) into format of the message you like. Here is doc reference: Using Liquid templates with set-body to know how you can use in APIM policy and note, this uses Liquid templating language, and that doc contains introduction about liquid templates, usage, filters etc.

    For your example, to extract version from the body, use the below snippet:

    <set-header name="Content-Type" exists-action="override">
                <value>application/json</value>
            </set-header>
            <set-body template="liquid">
                { 
                    "version": { 
                        {{body.collection.version}}
                    }
                }
            </set-body>
    

    Output (from test console in portal):
    User's image

    However, I noticed that you are using return-response policy in such cases liquid template is not supported. Refer SO thread which describes a solution to modify the body template before using it in return-response or just remove properties you don't need from body like this thread or try using custom policy expressions (C# syntax) with the below sample:

    <inbound>    
            <set-variable name="version" value="@{  
                        JObject inBody = context.Request.Body.As<JObject>(preserveContent: true);   
                        return (string)inBody["collection"]["version"]; 
                    }" />
            <base />
        </inbound>
        <backend>
            <base />
        </backend>
        <outbound>
            <return-response>
                <set-status code="200" reason="OK" />
                <set-header name="Content-Type" exists-action="override">
                    <value>application/json</value>
                </set-header>
                <set-body>@("{\"version\": " + (string)context.Variables["version"] + "}")</set-body>
            </return-response>
            <base />
        </outbound>
    

    Note, in my test I passed on the data in request body, but you can try similar approach with Response object. But make sure to construct the whole value for policy (not part of it).

    I hope this helps with your issue and let me know if you have any questions.


    If you found the answer helpful, please consider marking it as "Yes".


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.