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!
Add this line to your application's Gemfile:
gem 'alchemy-graphql', github: 'AlchemyCMS/alchemy-graphql'
And then execute:
$ bundle
There are two ways of setting up the GraphQL API for AlchemyCMS.
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
)
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
We recommend using GraphiQL in your app to have an interactive API explorer in your browser.
We also provide an online demo for you to play with:
https://demo.alchemy-cms.com/graphiql
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"
}
}
}
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"
}
}
}
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"
}
}
}
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"
}
}
}
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"
}
]
}
}
The gem is available as open source under the terms of the BSD-3-Clause License.