uber / zanzibar

A build system & configuration system to generate versioned API gateways.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unable to use list<X> in a HTTP query parameter results in panic

jacobgreenleaf opened this issue · comments

When decoding URI parameters for HTTP requests, zanzibar lacks an encoder and decoder for list Thrift types, e.g. list<string>. Currently this causes a panic due to a failing type switch when trying to create the encoder or decoder.

A standard encoding of composite types is undefined. RFC 3986 § 3.4 merely says:

[...] query components are often used to carry identifying information in the form of "key=value" pairs

but defines no convention for delimiters or encodings of complex types like maps or lists, leaving it up to the particular HTTP daemon to decide.

Golang net standard library will encode a list e.g. foo=[a, b] as foo=a&foo=b:

	v := url.Values{}
	v.Set("name", "Ava")
	v.Add("friend", "Jess")
	v.Add("friend", "Sarah")
	v.Add("friend", "Zoe")
	// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"

Decoding is done by using the map access since url.Values is typedef of a map[string][]string.

Zanzibar has support for struct types in URL parameters by using a dotted notation: a.b=foo would map b as a string property on struct a. This creates ambiguity if we add support for list types; a.b.c=foo&a.b.c=bar can be decoded to either of these structs:

As c is list of string:

struct A {
    1: required B b
}

struct B {
    1: required list<string> c
}

Or as b is list of struct:

struct A {
    1: required list<B> b
}

struct B {
    1: required string c
}

To avoid this ambiguity, we should restrict lists to scalar types.