autorest.typescript
autorest.typescript copied to clipboard
Paginated operations don't work properly if query param names in nextLink are URL-encoded
Repro steps:
- Generate client from spec that has a paginated operation with next link
- Have the pagination operation have a dollar-prefixed query parameter, such as
$top
- Invoke the paginated operation, as in the example below:
const it = await client.myResources.list({ top: 1 });
const results = [];
for await (const result of it) {
results.push(result);
}
- While resolving the iterator, the lib will make a first call to the server containing the
$top
parameter:GET https://example.com/myResources?$top=1
- The server will respond with something like the following, with
$top
having the$
encoded:
{
"value": [{}]
"nextLink": "https://example.com/myResources?%24top=1"
}
- The lib will then issue a next call, appending the original
$top
again at the end of the request, which causes a failure in the server because the$top
parameter is being defined twice:GET https://example.com/myResources?%24top=1&$top=1
Note: if the server does not return the param name encoded, the lib is able to dedupe the params correctly and send only one value as expected. However, the URL search params standard mandated the names to be encoded (https://url.spec.whatwg.org/#urlsearchparams).
Examples:
-
Encoded parameters in the
nextLink
response will cause duplicate params: -
If the params are not encoded in the
nextLink
, the link works as expected:
@xirzec Looks like this is a data plane SDK issue ?
Looks related to https://github.com/Azure/azure-sdk-for-js/issues/20420
We should avoid URLSearchParams
when constructing query param strings as it formats them as application/x-www-form-urlencoded
which is not the same as how query strings get encoded in normal URLs.
Interestingly, it seems like the server is doing the unnecessary encoding in this case. It doesn't appear that the URL constructor parses this by default:

So we'd have to reconstruct the query string by iterating over url.searchParams.entries
ourselves and re-encode it correctly. My biggest concern is this might cause us to un-encode values that other services expect to not be unwrapped.
I think my position on this is the server shouldn't be sending us a nextLink
it is not prepared to receive requested verbatim.
@xirzec Does this PR https://github.com/Azure/autorest.typescript/pull/1661 fix the issue here ?
@xirzec Does this PR #1661 fix the issue here ?
The PR I believe uses the original link as sent by the service, which is the expected behavior.