Query parameters do not support nested maps
When using Plug, we are able to serialize nested maps to query params.
e.g. Plug.Conn.Query.encode(%{filters: %{ name: "dave", direction: "asc", pagination: %{ page: 1} } }) which would give us something like filters[direction]=asc&filters[name]=dave&filters[pagination][page]=1"
Would you be open to a PR which either used Plug's implementation directly or re-implemented the algorithm?
Ideally, we shouldn't depend on Plug since Telsa is about something else, so in the best scenario, Plug and Tesla would use the same package.
If I am not mistaken, these types of serialization became popular with OpenAPI and they have some names for it https://swagger.io/docs/specification/serialization/ maybe it is worth having some packages shared, but I am not sure if Plug peeps would take the suggestion.
Worth mentioning, that Tesla doesn't know about the serialization strategy of such query params and most likely are pluggable based on the specification of their APIs, so whatever we do, it needs to be taken into consideration.
Thoughts?
Plug doesn't have a dependency, it has it's own implementation https://github.com/elixir-plug/plug/blob/v1.13.6/lib/plug/conn/query.ex#L203-L279
I'm not sure what the deal is with OpenAPI. Looking at that reference list, the only strategy I've very seen is deepObject and (infrequently) form.
Plug seemed like the logical implementation to me, because Tesla is very Plug like.
Seems like the issue hasn't come up before when I looked through the issues list, so maybe it's just something a small number of users would care about.
We were able to work around it by directly encoding using Plug.Conn.Query.encode and appending to the URL used by Tesla.
Personally, I'd only add the deepObject variant because it would be compatible with what already exists, just extending support for some extra data structures.
To collect more implementations, I recently had to do the following one
defp encode_query(query) do
query
|> Enum.map(fn
{k, v} when is_binary(v) -> "#{k}=#{v}"
{k, v} when is_list(v) -> Enum.map(v, &"#{k}=#{&1}")
end)
|> List.flatten()
|> Enum.join("&")
end
Haven't done objects because we don't have a need for it
Twilio's Ruby implementation (based on OpenAPI) has a flatten function which turns {a: {b: {c: 3}}} to {"a.b.c" => 3} to that using your encode_query approach, we would see a.b.c=3 or a.b.c=3&a.b.c=4 for a list.