mcintyre1994
What's the most idiomatic way to go from JSON body -> struct in Phoenix?
If I have a struct (with maybe some nested structs), and it has atom keys, what’s the most idiomatic way to get from user input in the form of a JSON request body to that struct? In my day job I use Scala + Play Framework and this is really easy to do, but I think in Elixir I’m getting caught up on the fact that user input → atom is a DoS vector.
So Phoenix presents my JSON body to my controller function in conn.body_params, nicely parsed into a map - with string keys. I can’t parse this to a struct using Kernel.struct because the string keys are ignored - and I can’t convert them to atoms without a potential DoS.
The only thing I can think of that would probably work is converting that map back into JSON, and then decoding it using Poison’s as parameter. But that seems really wasteful because Plug already converted it from JSON → map, then I’m doing map → JSON → struct.
I guess I’m wondering if there’s anything more idiomatic/automated/safe than just doing something like this in the controller:
body_params = conn.body_params
user = %User{
name: body_params["name"],
age: body_params["age"],
occupation: %Occupation{
job_title: body_params["occupation"]["job_title"]
}
}
Which seems quite error prone and tedious particularly where there’s a lot of nesting, JSON lists, etc.
Marked As Solved
kokolegorille
Converting data from the outside is usually done with changesets in Elixir, with or without database.
Something like
{:ok, user} = %User{}
|> User.changeset(body_params)
|> Ecto.Changeset.apply_action(:insert)
Also Liked
kokolegorille
Hello and welcome,
This could lead to potential :atom overflow,
ityonemo
I think half the elixir community is waiting for the ecto team to break off changesets like Phoenix did with pubsub.
fxn
Nice thing about changesets is that you can still define an embedded schema and get casts and validations.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









