jeromedoyle
JSON API response to Structs using Ecto Schema
Does anyone have an example of using Ecto Schemas for parsing JSON api responses?
I’m curious how you can convert this
{
"id": 283230,
"fname": "John",
"lname": "Smith",
"email": "john.smith@example.com",
"createdOn": "2016-03-31T10:49:11.386-05:00",
"updatedOn": "2016-10-31T16:36:12.968-05:00",
"_embedded": {
"addresses": [
{
"city": "Minneapolis",
"state": "MN"
},
{
"city": "New Orleans",
"state": "LA"
}
]
}
}
into this
%User{
id: 283230,
fname: "John",
lname: "Smith",
email: "john.smith@example.com",
createdOn: "2016-03-31T10:49:11.386-05:00",
updatedOn: "2016-10-31T16:36:12.968-05:00",
addresses: [
%Address{
"city": "Minneapolis",
"state": "MN"
},
%Address{
"city": "New Orleans",
"state": "LA"
}
]
}
Most Liked
IvanR
One alternative valid way is to use Jason and plain structs with @type t :: ... definitions plus Domo for validation.
Considering MapShaper module from this example app, the structs can be defined like:
defmodule Address do
@moduledoc false
use Domo
defstruct [city: "", state: ""]
@type t :: %__MODULE__{city: String.t(), state: String.t()}
end
defmodule User do
@moduledoc false
use Domo
today = NaiveDateTime.utc_now()
defstruct [id: 0, fname: "", lname: "", email: "", createdOn: today, updatedOn: today, addresses: [%Address{}]]
@type t :: %__MODULE__{
id: non_neg_integer(),
fname: String.t(),
lname: String.t(),
email: String.t(),
createdOn: NaiveDateTime.t(),
updatedOn: NaiveDateTime.t(),
addresses: [Address.t()]
}
defimpl MapShaper.Target do
def translate_source_map(_value, map) do
addresses = get_in(map, ["_embedded", "addresses"])
created_on = map |> get_in(["createdOn"]) |> parse_date()
updated_on = map |> get_in(["updatedOn"]) |> parse_date()
map
|> Map.put("addresses", addresses)
|> Map.put("createdOn", created_on)
|> Map.put("updatedOn", updated_on)
end
defp parse_date(str) do
str
|> NaiveDateTime.from_iso8601()
|> then(fn
{:ok, date_time} -> date_time
_ -> nil
end)
end
end
end
And parsing + validation that looks like:
with {:ok, binary} <- File.read("user.json"),
{:ok, map} <- Jason.decode(binary),
user = MapShaper.from_map(%User{}, map),
{:ok, user} <- User.ensure_type_ok(user) do
user
end
Returns the following nested struct for the valid input:
%User{
id: 283230,
fname: "John",
lname: "Smith",
email: "john.smith@example.com",
createdOn: ~N[2016-03-31 10:49:11.386],
updatedOn: ~N[2016-10-31 16:36:12.968],
addresses: [
%Address{city: "Minneapolis", state: "MN"},
%Address{city: "New Orleans", state: "LA"}
]
}
1
Popular in Questions
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
Hey all,
I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
Hi everyone,
I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
Hello everyone,
I try to use an Javascript Event Handler in my root.html.leex file.
Therefore I created a function in the app.js file: ...
New
Hi!
Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New
Other popular topics
Hello, how can I check the Phoenix version ?
Thanks !
New
Hi there,
I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
Lets say I have map like this fetching from my database
%{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
i’m a new one to elixir
which editor can i use
vs code? or atom?
Thanks! :smiley:
New
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
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










