Yson
Run json/graphql requests and parse responses in an easy way!
Installation
The package can be installed by adding yson to your list of dependencies in mix.exs:
def deps do
[
{:yson, "~> 0.2.2"}
]
endUsage
yson can be used both to run GraphQL requests and to parse JSON responses.
GraphQL
First create a Yson.GraphQL.Schema object:
defmodule User do
use Yson.GraphQL.Schema
query :user do # defines a query on :user
arg :person do
arg(:full_name, :string)
end
end
root do
value(:email)
map :person, resolver: &User.person/1 do
interface :natural_person do
value(:first_name)
value(:last_name)
end
interface :legal_person do
value(:company_name)
end
end
end
def person(%{company_name: name}), do: %{full_name: name}
def person(%{first_name: name, last_name: surname}), do: %{full_name: "#{name} #{surname}"}
endThen run a Graphql request using Yson.GraphQL.Api:
alias Yson.GraphQL.Api
variables = %{full_name: "john doe"}
headers = [] #optional
options = [] #optional
{:ok, result} = Api.run(User, variables, "https://mysite.com/graphql", headers, options)The result will be already mapped using resolvers, so it could be something like the following:
%{
user: %{
email: "a@b.c",
person: %{
full_name: "legal name"
}
}
}Custom usage
The Yson.GraphQL.Schema object exposes two methods:
&describe/0, to build the object description.&resolvers/0, to build the object resolvers tree.
that can be combined with the modules Yson.GraphQL.Builder and Yson.Parser.
Create query
Yson.GraphQL.Builder.build/2 accepts a Yson description and the variables. It can be used as follows:
iex> Yson.GraphQL.Builder.build(User.describe(), variables)
iex> %{
query: "query ($fullName: String) {\n user(person: {fullName: $fullName}) {\n email\n person {\n ... on LegalPerson {\n companyName\n }\n ... on NaturalPerson {\n firstName\n lastName\n }\n }\n }\n}",
variables: %{full_name: "john doe"}
}Parse response
Yson.Parser.parse/3 accepts a Yson resolvers tree and the payload (map with atom keys). It can be used as follows:
iex> payload = %{user: %{email: "a@b.c", person: %{companyName: "legal name"}}}
iex> Yson.Parser.parse(User.resolvers(), payload, :snake)
iex> %{
user: %{
email: "a@b.c",
user: %{
full_name: "legal name"
}
}
}JSON
Currently there is no implemented Api module for running Json requests, but it is still possible to use yson to parse responses.
Define schema
The first step is to define a Yson.Json.Schema schema.
defmodule User do
use Yson.Json.Schema
root do # defines the object root
value(:email)
map :person, resolver: &User.person/1 do
interface :natural_person do
value(:first_name)
value(:last_name)
end
interface :legal_person do
value(:company_name)
end
end
end
def person(%{company_name: name}), do: %{full_name: name}
def person(%{first_name: name, last_name: surname}), do: %{full_name: "#{name} #{surname}"}
endParse response
Yson.Parser.parse/3 accepts a Yson resolvers tree and the payload (map with atom keys). It can be used as follows:
iex> payload = %{email: "a@b.c", person: %{companyName: "legal name"}}
iex> Yson.Parser.parse(User.resolvers(), payload, :snake)
iex> %{email: "a@b.c", user: %{full_name: "legal name"}}The available strategies for key recasing are:
:snaketo convert payload keys to snake case before parsing:camelto convert payload keys to camel case before parsing:no_caseto preserve the original casing