0
votes

Using policies in Azure API Management, I'm trying to rename a query parameter, but it does not work. If I change copy-unmatched-params="false" to copy-unmatched-params="true" then it works, but the behaviour becomes that all unmatched parameters will get passed to the backend API which would allow clients to inject their own query params into the backend request which we do not want.

Everything else is fine.

I want to transform a request that comes in that looks like this:

https://{site}/search?query=dylan

To:

https://{backend-site}documents?api-version=2018-1-11&amount=1000&searchFields=Album,Artist&search=dylan

The only part that doesn't work is transforming the query parameter to be named "search" instead of query without allowing all parameters to be passed on from the inbound querystring. How can I fix that?

<policies>
    <inbound>
        <rewrite-uri template="/" copy-unmatched-params="false" />
        <set-header name="api-key" exists-action="override">
            <value>THIS-IS-API-KEI</value>
        </set-header>
        <set-query-parameter name="api-version" exists-action="override">
            <value>2018-1-11</value>
        </set-query-parameter>
        <set-query-parameter name="amount" exists-action="override">
            <value>1000</value>
        </set-query-parameter>
        <set-query-parameter name="searchFields" exists-action="override">
            <value>Album,Artist</value>
        </set-query-parameter>
        <set-query-parameter name="search" exists-action="override">
            <value>@(context.Request.Url.Query.GetValueOrDefault("query"))</value>
        </set-query-parameter>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>
3

3 Answers

1
votes

The reason why you're getting empty value from your last expression is because by that time your URI already rewritten to "/" and only "api-version", "amount", and "searchFields" query parameters are set. There are a few ways to go about that:

  1. Refer to original Url: @(context.Request.OriginalUrl.Query.GetValueOrDefault("query"))
  2. Add query to operation URI template - search?query={query} - and refer it from rewrite-uri policy: <rewrite-uri template="/?query={query}" copy-unmatched-params="false" />. The downside is that "query" parameter becomes required, so any request without it will result in 404.
1
votes

Try using variables. Assign the value to variable in the beginning and use the variable for assigning new query parameter

0
votes

You may rename parameter in the query by using string of the URL and simple replace method. In that case, the parameter wouldn't be mandatory.

<inbound>
     <base />
     <rewrite-uri template="@{
        return "/some-url-here-or-your-previously-constructed-url" + context.Request.OriginalUrl.QueryString
            .Replace("old-name", "new-name");
         }" copy-unmatched-params="false" />
 </inbound>