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
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
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
What is the proper way to load a module from a file in to IEX?
In the python world, doing something like this pretty standard:
from ....
New
Hi All,
I set a environment variables in dev.exs , like below code.
when i start server, how can i set the ${enable} value?
thanks.
d...
New
Good day to you all.
I have been struggling to get a query involving like and ilike to work.
Can anyone assist me on this, please?
pro...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Other popular topics
Update:
How to use the Blogs & Podcasts section
You can post links to your blog posts or podcasts either in one of the Official Blog...
New
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
Hello!
tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability.
After spen...
New
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
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









