Mike
Mike

Reputation: 5499

How can I parse a querystring using liquid template in Azure API-Management set-body?

I hope someone sees this and know exactly what to do. I feel like I tried everything :(. To give a little background, I'm trying to create a generic rest endpoint to proxy a SOAP reporting service backend and pass the query string keyValues as parameters.

I started down the path using context.Request.OriginalUrl.Query which is: IReadOnlyDictionary<string, string[]> and loop through the keys and values. This is my preferred method but I was recieving the error:

Liquid syntax error: Object '[p_customer_name, System.String[]]' is invalid because it is neither a built-in type nor implements ILiquidizable

Code to produce above:

<v2:listOfParamNameValues>
    {% for parameter in context.Request.OriginalUrl.Query %}
    <v2:item><v2:name>{{parameter.Key}}</v2:name><v2:values>
            {% for value in parameter.Value %}
            <v2:item>{{value}}</v2:item>
            {% endfor %}
        </v2:values></v2:item>
    {% endfor %}
</v2:listOfParamNameValues>

I gave up on that and began to parse the QueryString myself just so I could move on but using Split: &amp; or Split: '&amp;' just seem to ignore the & and Split: '&' causes an error:

One or more fields contain incorrect values: An error occurred while parsing EntityName. Line 15, position 123.

<v2:listOfParamNameValues>{% assign parts = context.Request.OriginalUrl.QueryString | Remove-First: '?' | Split:'&amp;' -%}
    {%- for part in parts -%}
        {%- assign keyValues = part | Split:'=' -%}
        {%- for keyValue in keyValues -%}
            {{-keyValue[0]}}:{{keyValue[1]-}}
        {%- endfor -%}
     {%- endfor %}</v2:listOfParamNameValues>

I'm open to any ideas, let me know if there is anything else I can add that may help.

Thank you!

Upvotes: 2

Views: 3687

Answers (2)

roberto-mardeni
roberto-mardeni

Reputation: 181

There seems to be a limitation when using the Ampersand to do a split within the API Management policies inside of the set-body with liquid template.

To get around that I used an additional policy, like this:

<inbound>
    <base />
    <set-variable name="query_string_params" value="@(context.Request.OriginalUrl.QueryString.Substring(1).Replace("&","|"))" />
    <set-body template="liquid">
        {% assign parameters = context.Variables["query_string_params"] | Split: "|" %}
        <parameters>
        {% for p in parameters %}
            <parameter>
                {% assign parts = p | Split: "=" %}
                <name>{{parts.first}}</name>
                <value>{{parts.last}}</value>
            </parameter>
        {% endfor %}
        </parameters>
    </set-body>
</inbound>

Hope this helps!

Upvotes: 2

David Jacquel
David Jacquel

Reputation: 52779

Liquid filters are case sensitive an it seems that dotliquid uses this convention by default.

{% assign parts = context.Request.OriginalUrl.QueryString | remove_first: '?' | split:'&' -%}

Upvotes: 0

Related Questions