GraphQL

A query language for your API

(and what it means for Content Management)

Overview

Alternative to REST and SOAP

A specification created by Facebook

GraphQL servers in many languages (Node, PHP, etc)

Used by the new Github API, Pinterest, Shopify, ...

Motivation

Smart schema, smart clients

Strict typing, self-documenting

Inline "resources" in a single call

Strict REST

GET /api/v1/currentUser
GET /api/v1/menu
GET /api/v1/file/?parent=0
GET /api/v1/file/99/history
GET /api/v1/file/99/usage
GET /api/v1/file/99/actions

Kind of REST

GET /api/v1/config
GET /api/v1/file/
  ?parent=0
  &include=id,title,url,history,related,actions

Still kind of REST

GET /api/v1/config
GET /api/v1/file/
  ?parent=0
  &include=id,title,url,history,related,actions
  &fields=history.date,history.version

Giving up on REST

GET /api/v1/currentUser
GET /api/v1/menu
GET /api/v1/file/
  ?parent=0
  &include=history,related,actions
  &fields=history.date,history.version
  &history.limit=5

Text

Text

Text

type File {
  id: ID!
  title: String
  url: String
  size: Int
}​
query ReadFiles() {
  readFiles(limit:20) {
    id
    title
    url
  }
}
[
  {
    "id": 98,
    "title": "otto",
    "url": "otto.jpg"
  },
  {
    "id": 99,
    "title": "john",
    "url": "john.doc"
  }
]​

Text

Text

query ReadFiles() {
  readFiles(limit:20) {
    id
    title
    url
    related {
      id
      title
      url
    }
    history(limit: 5) {
      version
      date
    }
    actions {
      name
    }
  }
}
[
  {
    "id": 98,
    "title": "otto",
    "url": "otto.jpg",
    "related": [
      {
        "id": 1,
        "title": "otherfile",
        "url": "otherfile.jpg"
      }
    ],
    "history": [ /* ... */ ],
    "actions": [ /* ... */ ]
  },
  /* ... */
]
query ReadFiles() {
  readFiles(limit:20) {
    id
    title
    url
    related {
      id
      title
      url
    }
    history(limit: 5) {
      version
      date
    }
    actions {
      name
    }
  }
}
[
  {
    "id": 98,
    "title": "otto",
    "url": "otto.jpg",
    "related": [
      {
        "id": 1,
        "title": "otherfile",
        "url": "otherfile.jpg"
      }
    ],
    "history": [ /* ... */ ],
    "actions": [ /* ... */ ]
  },
  /* ... */
]
type File {
  id: ID!
  title: String
  url: String
  size: Int
  history: [FileVersion]
  related: [File]
  actions: [ContentAction]
}​

Headless CMS

Content API

Disadvantages

Caching gets harder

Types vs. OOP inheritance

Full use only through async data fetching

No HATEOAS

Thanks

twitter.com/chillu

silverstripe.org/4

github.com/silverstripe/silverstripe-graphql

graphql.org

Fitting GraphQL into a CMS Content Model

By chillu

Fitting GraphQL into a CMS Content Model

Lightning talk for the PHP UG in Wellington (Feb 2017)

  • 1,586