-
Notifications
You must be signed in to change notification settings - Fork 577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plug.Conn.Query encode question #1087
Comments
Given we raise today, We can simply support the new format, so a pull request That does so is welcome. We need to make sure we parse it correctly too |
By parse you mean the I see the fun sig has a few more params than the encode one,
But until a new major plug version the current signature can't change, so the solution would be adding a new optional keyword param at the end? The usual approach for optional params is keyword and get the option from it right? It will only be a single param right now, but not sure if we should translate it into a map on the first iteraction, to then be able to do cleaner guards in the inner funs? ps: thanks for all the work you do José |
We may not need an option. I think that it will work just fine but you need to double check. |
Decoding it seems to work as of now to parse, where ie: Plug.Conn.Query.decode("test=yeap&payment_method_types[0]=card&payment_method_types[1]=acss_debit")
%{
"payment_method_types" => %{"0" => "card", "1" => "acss_debit"},
"test" => "yeap"
} Although one might expect to see a list on I've just written something that seems to work, but it needs to generate a couple function clauses through metaprogramming: # simple lists
Plug.Conn.Query.decode("test=yeap&payment_method_types[0][test]=card&payment_method_types[1][test]=acss_debit")
# nested maps
Plug.Conn.Query.decode("test=yeap&payment_method_types[0][test]=card&something_else=20&payment_method_types[1][test]=acss_debit")
# complex nesting
Plug.Conn.Query.decode("test=yeap&payment_method_types[0][test]=card&something_else=20&payment_method_types[1][second][0]=acss_debit&payment_method_types[1][second][1]=anotheR_one") Would parse respectively as: # simple lists
%{
"payment_method_types" => ["card", "acss_debit"],
"something_else" => "20",
"test" => "yeap"
}
# nested maps
%{
"payment_method_types" => [%{"test" => "card"}, %{"test" => "acss_debit"}],
"something_else" => "20",
"test" => "yeap"
}
# complex nesting
%{
"payment_method_types" => [
%{"test" => "card"},
%{"second" => ["acss_debit", "anotheR_one"]}
],
"something_else" => "20",
"test" => "yeap"
} In case an array is specified by |
The thing is, if it's worth adding any of this to Plug. The encoding won't hurt to have in plug I guess. Because for my usage the parsing doesn't really pose a problem because changesets can handle it the way it's built. It's just the outgoing body that I need to encode (in this particular case) without required the user to pass params that in the spec show as lists, as a map. |
Yes, lists are only if you don't specify any key at all. So it is expected for all of these to be maps and I wouldn't change it. In fact, I now think your answer is to use maps. Your input should be this:
Also note that, afaik, there is no specification for this, so everyone pretty much rolls with whatever they want. |
Yeap, I can agree with that, hence why I decided to ask first. I know indeed it works when done like that, my issue is trying to reconcile automatically generating typespecs from oapi specs with the encoding (I'll personally opt to allow the list mode, but since I was using Plug.Conn.Query for the body wondered if this was something wanted as encoding doesn't present any problem), because in this particular case if you read the stripe docs, it says a list of objects, and you might jump to writing it as a list in your function calls - you would need to read the typespec very carefully/remember the gotcha to see it would be a map and not a list. And the typespecs get pretty long, https://hexdocs.pm/exoapi_stripe/0.1.3/ExOAPI.Stripe.SDK.Checkout.html#post_checkout_sessions/2 I could also special case this type when generating the typespecs but that might even be more complex. Anyway, thanks. I'll close this, if wanted at some point just re-open |
We could change encode with the caveat that decode will return a different structure and I am not sure if that’s a good idea. |
If OpenAPI specifies how things should be encoded, then perhaps it should be part of the OpenAPI lib. :) |
This is indeed a problem with spec/stripe side not Plug.Conn.Query per se José, but since I'll have to write it anyway was checking if it would make sense to PR, just that! |
Makes total sense, thanks! |
Hi,
I ran into two situations when encoding parameters for x-www-formurlencoded using
Plug.Conn.Query.encode
for body requests and I wanted to understand if this is working according to the spec and is stripe's parsing/documentation that is out of spec, or if this out of scope for this module, or is something that should be changed (enabled/allowed), and if so, if a PR for it is welcomed - since I will do some work on this for my own needs anyway.First is the error that is raised when a map has more than 1 key inside a list.
results in:
Here I'm not sure why the raise was implemented so I might be missing something? If this was
That seems to encode properly the information?
The second is related to that as well, even if there's only a single key, it will encode lists as
[][map_key]
instead of[n_index][map_key]
.I've noticed something that is probably related to this when using phoenix with embeds/assocs and
inputs_for
where the params submitted through the form are decoded as a map keyed by the index instead of a list. Changesets deal with it as if it was a list, but the first time I thought something was wrong on my forms now I see that this might be somehow related.Stripe does accept the
[]
notation for primitive lists though, so it's also not very consistent, although it seems to also accept the[n_index]=primitive
in those cases as well, but doesn't accept[]
for some cases.I've ran into this as I've been writing a lib to generate SDK clients from open api 3 specs ex_aopi stripe. And when generating them for stripe, there's instances (i.e.: line items, https://stripe.com/docs/api/checkout/sessions/create ) where both their doc and open api spec include define lists (arrays in oapi) for a field with object items (it might also be that for this instance, since the order of the line items is possibly important, they require index fields, but given an array/list is naturally ordered it seems they could do away with it... not sure if it's any shortcoming or to ease their parsing side either).
To summarize, wanted to know if someone has looked into this previously, and the reasons for it working as it is.
If wanted, a simple solution would be to add another optional arg, to how to encode lists (this would keep backwards compatibility, while enabling one to pass
lists_as: :indexed
), and do indexed based encoding for listsThanks!
The text was updated successfully, but these errors were encountered: