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"
}
]
}
First Post!
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
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
Hello!
Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
What is the idiomatic way of matching for not nil in Elixir?
E.g.,
First way:
defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
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
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
I am trying to run a deploy with docker and I successfully runned with this command:
docker build -t romenigld/blog-prod .
but when I t...
New
Other popular topics
Hi!
In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir?
Searched the docs for ip address and the web, no good results.
Thanks!
New
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
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
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I’m writing a test for one of the...
New
I am trying to run a deploy with docker and I successfully runned with this command:
docker build -t romenigld/blog-prod .
but when I t...
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









