Skip to content

Support Arrays In Query String #168

Open
@PCOffline

Description

@PCOffline

There is a convention for the syntax to pass an array in query parameters:

  1. Passing the same parameter multiple times:
    ?foo=bar&foo=qux
  2. Passing the same parameter multiple times with a [] suffix:
    ?foo[]=bar&foo[]=qux - URL encoded as ?foo%5B%5D=bar&foo%5B%5D=qux
  3. Passing the same parameter multiple times with an explicit index in the [] suffix:
    ?foo[0]=bar&foo[1]=qux - URL encoded as ?foo%5B0%5D=bar&foo%5B1%5D=qux
    or, to demonstrate the functionality of the explicit index:
    ?foo[1]=qux&foo[0]=bar - URL encoded as ?foo%5B1%5D=qux&foo%5B0%5D=bar
  4. Passing a comma-separated list:
    ?foo=bar,qux

Sadly, there is no unified standard or W3C spec, and every library and framework handles these cases differently.
As of today, none of these options will produce an array in Azure Functions.

The change I propose is a breaking change, so perhaps an opt-in should be added, or it could be merged to version 5 if such a version is upcoming.

Investigative information

N/A

Repro steps

  1. Create a sample HTTP function that prints its query parameters
  2. Send a request that uses one of the syntaxes for arrays in query params (for example ?foo[]=bar&foo[]=qux)

Expected behaviour

We should receive an object that contains the parameter as the field and an array as the value.
For example, when sending ?foo[]=bar&foo[]=qux we should get `{ foo: ["bar", "qux"] } as our query.

Actual behaviour

"?foo=bar&foo=qux"         => { "foo": "bar,qux" }
"?foo[]=bar&foo[]=qux"     => { "foo[]": "bar,qux" }
"?foo[1]=qux&foo[0]=bar"   => { "foo[0]": "bar", "foo[1]": "qux" }
"?foo=bar,qux"             => { "foo": "bar,qux" }

Known workarounds

A workaround is available if we utilize the qs (short for query string) or query-string libraries and parse the query params with the next code:
Be advised this code is overly simplified and does not cover edge cases.

import type { AzureFunction, Context, HttpRequest } from "@azure/functions";
import qs from "qs";

const httpTrigger: AzureFunction = async (context: Context, req: HttpRequest): Promise<void> => {
  const query = qs.parse(req.url.split("?")[1]);
  context.res = { body: query };
}

qs and query-string are two powerful libraries that can parse query parameters into arrays and optionally, even to objects.
Be advised, however, that both libraries require certain options to be passed to handle arrays for different syntaxes and avoid unexpected behaviour, especially when it comes to trickier parts like objects.

Related information

Provide any related information

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions