View Source Plug and Phoenix Setup
First, install Absinthe.Plug and a JSON codec of your choice, eg, Jason:
# filename: mix.exs
def deps do
[
{:absinthe_plug, "~> 1.5"},
{:jason, "~> 1.0"},
]
endPlug
To use, simply plug Absinthe.Plug in your pipeline.
plug Absinthe.Plug,
schema: MyAppWeb.SchemaIf you are going to support content types other than simply application/graphql
you should plug Absinthe.Plug after Plug.Parsers.
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json, Absinthe.Plug.Parser],
json_decoder: Jason
plug Absinthe.Plug,
schema: MyAppWeb.SchemaFor more information on how the content types work, see General Usage.
Phoenix
If your entire API is going to be based on GraphQL, we recommend simply plugging Absinthe.Plug in at the bottom of your endpoint, and removing your router altogether.
defmodule MyApp.Endpoint do
use Phoenix.Endpoint, otp_app: :my_app
plug Plug.RequestId
plug Plug.Logger
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Jason
plug Absinthe.Plug,
schema: MyAppWeb.Schema
endIf you want only Absinthe.Plug to serve a particular route, configure your router
like:
defmodule MyAppWeb.Router do
use Phoenix.Router
resource "/pages", MyAppWeb.PagesController
forward "/api", Absinthe.Plug,
schema: MyAppWeb.Schema
endNow Absinthe.Plug will only serve GraphQL from the /api url.
Absinthe Context
Absinthe.Plug will pass any values found inside conn.private[:absinthe][:context]
on to Absinthe.run as the context. This is how you should handle logic that
uses headers -- most notably, Authentication.
For more information, see the Context guide.
GraphiQL
See the absinthe_plug
project and the GraphiQL portion of the Introspection guide to
learn how to use the built-in Absinthe.Plug.GraphiQL plug.
General Usage
This plug supports requests in a number of ways:
Via a GET
With a query string:
?query=query+GetItem($id:ID!){item(id:$id){name}}&variables={id:"foo"}Due to varying limits on the maximum size of URLs,
we recommend using one of the POST options below instead, putting the query into the body of the request.
Via an application/json POST
With a POST body:
{
"query": "query GetItem($id: ID!) { item(id: $id) { name } }",
"variables": {
"id": "foo"
}
}(We could also pull either query or variables out to the query string, just
as in the GET example.)
Via an application/graphql POST
With a query string:
?variables={id:"foo"}
And a POST body:
query GetItem($id: ID!) {
item(id: $id) {
name
}
}HTTP API
How clients interact with the plug over HTTP is designed to closely match that of the official express-graphql middleware.
In the example above, we went over the various ways to make a request, but here are the details:
Once installed at a path, the plug will accept requests with the following parameters:
query- A string GraphQL document to be executed.variables- The runtime values to use for any GraphQL query variables as a JSON object.operationName- If the providedquerycontains multiple named operations, this specifies which operation should be executed. If not provided, a 400 error will be returned if thequerycontains multiple named operations.
The plug will first look for each parameter in the query string, eg:
/graphql?query=query+getUser($id:ID){user(id:$id){name}}&variables={"id":"4"}If not found in the query string, it will look in the POST request body, using
a strategy based on the Content-Type header.
For content types application/json and application/x-www-form-urlencoded,
configure Plug.Parsers (or equivalent) to parse the request body before Absinthe.Plug, eg:
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: JasonFor application/graphql, the POST body will be parsed as GraphQL query string,
which provides the query parameter. If variables or operationName are
needed, they should be passed as part of the
Configuration Notes
As a plug, Absinthe.Plug requires very little configuration. If you want to support
application/x-www-form-urlencoded or application/json you'll need to plug
Plug.Parsers first.
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Jason
plug Absinthe.Plug,
schema: MyApp.Linen.SchemaAbsinthe.Plug requires a schema: config.
It also takes several options. See the documentation for the full listing.
Inside Phoenix controllers
You can use GraphQL as the datasource for your Phoenix controllers. For this
you'll need to add absinthe_phoenix to your dependencies. See Absinthe Phoenix for installation instructions.
@graphql """
query ($filter: UserFilter) {
users(filter: $filter, limit: 10)
}
"""
def index(conn, %{data: data}) do
render conn, "index.html", data
endThe results of the query are now available in the "index.html" template. For
more information, see Absinthe.Phoenix.Controller