Get Absinthe working with list and creating people.

This commit is contained in:
James Harton 2018-04-08 12:42:50 +12:00
parent 707452b649
commit 69f2bdbb75
7 changed files with 110 additions and 11 deletions

View file

@ -1,11 +1,24 @@
# What are we building?
# Getting started with Absinthe
This branch contains a very simple Phoenix app which displays a gallery of faces
imported from Gitbhub users. Shout out to
[Eduardo](https://github.com/edgurgel) for the cool
[Tentacat](https://hex.pm/packages/tentacat) package which made using the Github
API so easy.
[Absinthe](https://absinthe-graphql.org/) is an open source implementation of
the GraphQL server specification for Elixir. Note that I said "Elixir" there
and now "Phoenix". Absinthe doesn't need Phoenix, but we're going to use it in
this example because my guess is that not many people are making purely GraphQL
services and most of us are probably bolting it on to existing sites or
services.
[Demo](http://localhost:4000)
Absinthe has [truly amazing docs](https://hexdocs.pm/absinthe/overview.html).
Seriously. They're so great. You should check them out.
Now move on to the `step-3` branch.
In this branch we've added Absinthe to our project, and configured a type and a
schema for our list of people, and a migration which can import new people.
Look at:
* `mix.exs`
* `lib/faces_web/router.ex`
* `lib/faces_web/schema/schema.ex`
* `lib/faces_web/schema/person.ex`
* `lib/faces_web/resolvers/people.ex`
[Demo](http://localhost:4000/graphiql)

View file

@ -0,0 +1,30 @@
defmodule FacesWeb.Resolvers.People do
alias Faces.Gallery
@doc """
This is the resolver callback for Absinthe to find a list of all people.
The arguments are:
* `parent`, any parent object which Absinthe things we're related to.
* `args`, any arguments passed to the query.
* `resolution`,
"""
def list_people(_parent, _args, _resolution) do
{:ok, Gallery.list_people()}
end
@doc """
This is the resolver callback Absinthe uses to create a person.
The arguments are:
* `parent` any parent object which Absinthe things we're related to.
* `args` a map of arguments passed to the query.
* `context` a context object which can be used for things like
authentication, etc.
"""
def create_person(_parent, %{username: username}, _context) do
Gallery.import_user(username)
end
end

View file

@ -17,11 +17,14 @@ defmodule FacesWeb.Router do
# Use the default browser stack
pipe_through(:browser)
resources("/", FaceController)
resources("/", FaceController, only: [:index, :create])
end
# Other scopes may use custom stacks.
# scope "/api", FacesWeb do
# pipe_through :api
# end
forward("/api", Absinthe.Plug, schema: FacesWeb.Schema)
forward("/graphiql", Absinthe.Plug.GraphiQL, schema: FacesWeb.Schema)
end

View file

@ -0,0 +1,27 @@
defmodule FacesWeb.Schema.Person do
use Absinthe.Schema.Notation
@desc "A person whose face we want to see"
object :person do
@desc "A unique identifier for this person"
field(:id, :id)
@desc "The person's Github username"
field(:username, :string)
@desc "The person's name as per Github"
field(:name, :string)
@desc "The person's location as per Github"
field(:location, :string)
@desc "The URL of the person's Github avatar image"
field(:avatar_url, :string)
@desc "When this user was first imported into the faces app"
field(:inserted_at, :datetime)
@desc "When this user was last updated in the faces app"
field(:updated_at, :datetime)
end
end

View file

@ -0,0 +1,22 @@
defmodule FacesWeb.Schema do
use Absinthe.Schema
alias FacesWeb.Resolvers
import_types(Absinthe.Type.Custom)
import_types(FacesWeb.Schema.Person)
query do
@desc "List all people"
field :people, list_of(:person) do
resolve(&Resolvers.People.list_people/3)
end
end
mutation do
@desc "Import a user from Github"
field :import_person, type: :person do
arg(:username, non_null(:string))
resolve(&Resolvers.People.create_person/3)
end
end
end

View file

@ -41,7 +41,9 @@ defmodule Faces.Mixfile do
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:cowboy, "~> 1.0"},
{:tentacat, "~> 0.9.0"}
{:tentacat, "~> 0.9.0"},
{:absinthe_plug, "~> 1.4"},
{:poison, "~> 2.1.0", override: true}
]
end

View file

@ -1,4 +1,6 @@
%{
"absinthe": {:hex, :absinthe, "1.4.10", "9f8d0c34dfcfd0030d3a3f123c7501e99ab59651731387289dad5885047ebb2a", [:mix], [{:dataloader, "~> 1.0.0", [hex: :dataloader, repo: "hexpm", optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"absinthe_plug": {:hex, :absinthe_plug, "1.4.2", "01bf16f0a637869bcc0a1919935f08ff853501004e7549ddaa3a7788deb48965", [:mix], [{:absinthe, "~> 1.4", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"certifi": {:hex, :certifi, "2.3.1", "d0f424232390bf47d82da8478022301c561cf6445b5b5fb6a84d49a9e76d2639", [:rebar3], [{:parse_trans, "3.2.0", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
@ -23,7 +25,7 @@
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.1.3", "1d178429fc8950b12457d09c6afec247bfe1fcb6f36209e18fbb0221bdfe4d41", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2 or ~> 1.3", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.2", "bfa7fd52788b5eaa09cb51ff9fcad1d9edfeb68251add458523f839392f034c1", [:mix], [], "hexpm"},
"plug": {:hex, :plug, "1.5.0", "224b25b4039bedc1eac149fb52ed456770b9678bbf0349cdd810460e1e09195b", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"poison": {:hex, :poison, "2.1.0", "f583218ced822675e484648fa26c933d621373f01c6c76bd00005d7bd4b82e27", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},