Plug and Phoenix

First, install Absinthe.Plug and a JSON codec of your choice, eg, Poison:

mix.exs
def deps do
  [
    {:absinthe_plug, "~> 1.1"},
    {:poison, "~> 2.1.0"},
  ]
end

Plug

To use, simply plug Absinthe.Plug in your pipeline.

plug Absinthe.Plug,
  schema: MyApp.Schema

If 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: Poison

plug Absinthe.Plug,
  schema: MyApp.Schema

For 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: Poison

  plug Absinthe.Plug,
    schema: MyApp.Schema
end
Sample Endpoint

If you want only Absinthe.Plug to serve a particular route, configure your router like:

web/router.ex
defmodule MyApp.Web.Router do
  use Phoenix.Router

  resource "/pages", MyApp.PagesController

  forward "/api", Absinthe.Plug,
    schema: MyApp.Web.Schema
end

Now 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 Using GraphiQL section 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:

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: Poison

For 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: Poison

plug Absinthe.Plug,
  schema: MyApp.Linen.Schema
Example plug module

Absinthe.Plug requires a schema: config.

It also takes several options. See the documentation for the full listing.