Bracket Notation
Bracket notation encodes structured data in flat key-value formats such as query strings and form data. OpenAPI Serializer, OpenAPI Handler, and OpenAPI Link use it whenever nested data must be represented outside plain JSON.
Rules
-
Repeated keys become arrays.
color=red&color=blue -> { color: ['red', 'blue'] } -
Append
[]to push into an array.color[]=red&color[]=blue -> { color: ['red', 'blue'] } -
Append
[number]to target an explicit array index.color[0]=red&color[2]=blue -> { color: ['red', <empty>, 'blue'] }::: info Missing indexes create sparse arrays.
Explicit indexes greater than
999are treated as object keys by default to avoid huge sparse arrays during deserialization. To change that limit, configuremaxExplicitDeserializingArrayIndex:const serializer = new OpenAPISerializer({ bracketNotation: { maxExplicitDeserializingArrayIndex: 1999, } }):::
-
Append
[key]to target an object property.color[red]=true&color[blue]=false -> { color: { red: 'true', blue: 'false' } }
Limitations
Bracket notation is designed to express structured data in constrained environments, so it has a few unavoidable limitations:
- Cannot represent empty structures like empty objects
{}or empty arrays[]. - Cannot represent an array at the root level. For example,
0=red&1=bluebecomes{ 0: 'red', 1: 'blue' }, not['red', 'blue']. - Cannot represent objects whose keys are all numbers, because they can be mistaken for array indexes.
- Cannot reliably represent keys that contain
[or].
Examples
URL Query
curl 'http://example.com/api/example?name[first]=John&name[last]=Doe'
This query is parsed as:
{
"name": {
"first": "John",
"last": "Doe"
}
}
Form Data
curl -X POST http://example.com/api/example \
-F 'name[first]=John' \
-F 'name[last]=Doe'
This form data is parsed as:
{
"name": {
"first": "John",
"last": "Doe"
}
}
Complex Example
curl -X POST http://example.com/api/example \
-F 'data[names][0][first]=John1' \
-F 'data[names][0][last]=Doe1' \
-F 'data[names][1][first]=John2' \
-F 'data[names][1][last]=Doe2' \
-F 'data[ages][0]=18' \
-F 'data[ages][2]=25' \
-F 'data[files][]=@/path/to/file1' \
-F 'data[files][]=@/path/to/file2'
This form data is parsed as:
{
"data": {
"names": [
{ "first": "John1", "last": "Doe1" },
{ "first": "John2", "last": "Doe2" }
],
"ages": ["18", "<empty>", "25"],
"files": ["<binary data>", "<binary data>"]
}
}
Learn More
The bracket notation is a small, self-contained module, making it easy to understand. To explore its behavior in detail, see the source code.