CircleCI Maintainability Test Coverage

AlchemyCMS GraphQL API

Add a GraphQL API to your AlchemyCMS powered site.

WARNING: This is in an early state and changes to the API may be applied without any further announcement!

Installation

Add this line to your application's Gemfile:

gem 'alchemy-graphql', github: 'AlchemyCMS/alchemy-graphql'

And then execute:

$ bundle

Setup

There are two ways of setting up the GraphQL API for AlchemyCMS.

Use the provided GraphQL endpoint

This is the easiest way of setting up the AlchemyCMS GraphQL API. Recommended for apps not having a GraphQL API or stand alone Alchemy installations.

# config/routes
Rails.application.routes.draw do
  mount Alchemy::GraphQL::Engine => '/'
  mount Alchemy::Engine => '/'
  ...
end

NOTE: It is necessary to mount the Alchemy::GraphQL::Engine before mounting the Alchemy::Engine otherwise Alchemys catch all route will make your GraphQL endpoint unreachable.

Your GraphQL endpoint will be available at /graphql.

TIP: Mounting the engine at a different path (ie /cms) will prefix the GraphQL endpoint with that path (ie. /cms/graphql)

Build your own GraphQL endpoint

This is the more advanced way of setting up the AlchemyCMS GraphQL API. It is recommended for apps already having a GraphQL API or people who want to build their own schema.

Include one or all of the provided fields in your GraphQL::Schema::Object class.

# app/graphql/query.rb
class GraphQL::Query < ::GraphQL::Schema::Object
  field :my_field, String, null: true
  include Alchemy::GraphQL::PageFields
end

Usage

We recommend using GraphiQL in your app to have an interactive API explorer in your browser.

Online demo

We also provide an online demo for you to play with:

https://demo.alchemy-cms.com/graphiql

Example queries

Find an Alchemy page by its name

query {
  page: alchemyPage(name: "A page") {
    name
    elements(only: "article") {
      contents(only: "headline") {
        ingredient
      }
    }
  }
}

will return

{
  "data": {
    "page": {
      "name": "A page",
      "elements": [
        {
          "contents": [
            {
              "ingredient": "My headline"
            }
          ]
        }
      ]
    }
  }
}

It is also possible to find pages by a name match instead of an exact name.

query {
  page: alchemyPage(name: "Contact", exactMatch: false) {
    name
  }
}

will return

{
  "data": {
    "page": {
      "name": "Contact us"
    }
  }
}

Find an Alchemy page by its urlname

query {
  page: alchemyPage(urlname: "a-page") {
    elements {
      contents {
        ingredient
      }
    }
  }
}

will return

{
  "data": {
    "page": {
      "elements": [
        {
          "contents": [
            {
              "ingredient": "My headline"
            },
            {
              "ingredient": "<p>My paragraph.</p>"
            }
          ]
        }
      ]
    }
  }
}

It is also possible to find pages by an urlname match instead of an exact urlname.

query {
  page: alchemyPage(urlname: "contact", exactMatch: false) {
    urlname
  }
}

will return

{
  "data": {
    "page": {
      "urlname": "contact-us"
    }
  }
}

Find an Alchemy page by several attributes

You can even combine attributes to narrow down the result.

query {
  page: alchemyPage(
    name: "Foot",
    pageLayout: "footer",
    exactMatch: false
  ) {
    name
  }
}

will return

{
  "data": {
    "page": {
      "name": "Footer"
    }
  }
}

Find an Alchemy element by its name

query {
  element: alchemyElement(name: "article") {
    name
    contents(only: "headline") {
      ingredient
    }
  }
}

will return

{
  "data": {
    "element": {
      "name": "article",
      "contents": [
        {
          "ingredient": "My headline"
        }
      ]
    }
  }
}

It is also possible to find elements by a name match instead of an exact name.

query {
  element: alchemyElement(name: "head", exactMatch: false) {
    name
  }
}

will return

{
  "data": {
    "element": {
      "name": "header"
    }
  }
}

Find Alchemy elements by name

query {
  elements: alchemyElements(only: "article") {
    name
    contents(only: "headline") {
      ingredient
    }
  }
}

will return

{
  "data": {
    "elements": [
      {
        "name": "article",
        "contents": [
          {
            "ingredient": "My first headline"
          }
        ]
      },
      {
        "name": "article",
        "contents": [
          {
            "ingredient": "My second headline"
          }
        ]
      }
    ]
  }
}

It is also possible to exclude elements by name.

query {
  elements: alchemyElements(except: "article") {
    name
  }
}

will return

{
  "data": {
    "elements": [
      {
        "name": "header"
      },
      {
        "name": "footer"
      }
    ]
  }
}

License

The gem is available as open source under the terms of the BSD-3-Clause License.