A GraphQL parser and resolver for Elixir.
This project is still a work in progress, but the eventual goal is to support the full GraphQL spec.
Build a basic AST from a doc
"{
user {
id,
firstName,
lastName
}
}" |> Plot.parse
# returns:
{:ok,
[{:query, nil,
[{:object, "user", nil, [],
[{:field, "id", nil, []},
{:field, "firstName", nil, []},
{:field, "lastName", nil, []}]}]}]}
Build Plot objects from a doc
"{
user {
id,
firstName,
lastName
}
}" |> Plot.parse_and_generate
# returns:
%Plot.Document{fragments: [],
operations: [%Plot.Query{name: nil,
objects: [%Plot.Object{alias: nil, args: [], name: "user",
fields: [%Plot.Field{alias: nil, args: [], name: "lastName"},
%Plot.Field{alias: nil, args: [], name: "firstName"},
%Plot.Field{alias: nil, args: [], name: "id"}]}]}],
variables: []}
Query resolution works via Elixir protocols. Implement the Resolution
protocol for the various nodes of your queries.
# Implementation
defimpl Plot.Resolution, for: Plot.Object do
def resolve(%Plot.Object{name: "user"} = _obj, _context) do
%{"firstName" => "Phil", "lastName" => "Burrows", dontInclude: "this"}
end
def resolve(%Plot.Object{name: "birthday"}, _context) do
%{"day" => 15, "month" => 12, "year" => 2015}
end
end
# Resolution
doc = "{user {firstName, lastName, birthday {month, year}}}" |> Plot.parse_and_generate
doc.operations |> Enum.at(0) |> Plot.Resolver.resolve
# returns:
[%{"user" => %{"birthday" => %{"month" => 12, "year" => 2015},
"firstName" => "Phil", "lastName" => "Burrows"}}]