From REST to GraphQL

How to build a GraphQL Server

About Me!

Christopher Vachon

Midland, Ontario

FullStack Developer

Beer Enthusiast and Home Brewer

Traveller

christophervachon.com

code@christophervachon.com

Christopher Vachon

Development Operations Manager

LabX Media Group

chrisv@labx.com

What I Do!

  • Build and Support Applications at Scale
  • Process Automation (CI/CD Pipelines)
  • Break Things!
  • Fix Them Before Anyone Notices
  • Build and Run Evaluations on Platforms and Technology

GraphQL

What is it?

title

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

GraphQL Homepage

Whats Covered?

Output of a RESTful API

Key Concepts of GraphQL

Setup of a GraphQL Server on NodeJS

Use Case

The Book Store App

Screen Shot of the BookStore Front End

A Couple of Notes

  • Node.JS Application
  • Sqlite3 Database
  • Service Modules for Interacting with the Database
  • Standard bare bones RESTful API

RESTful API

GET:/rest/books/

[
    // ...
    {
        "id": "IaNFbTL33g",
        "title": "Thrawn",
        "deck": "In this definitive novel, readers will follow Thrawn’s ...",
        "language": "english",
        "coverImage": "/images/91SxgwHMc0L.jpg",
        "publishDate": "2017-04-11",
        "created": "...",
        "updated": "... ",
        "isDeleted": 0
    }
    // ...
]

GET:/rest/books/:id

{
    "id": "IaNFbTL33g",
    "title": "Thrawn",
    "deck": "In this definitive novel, readers will follow Thrawn’s ...",
    "language": "english",
    "coverImage": "/images/91SxgwHMc0L.jpg",
    "publishDate": "2017-04-11",
    "created": "...",
    "updated": "... ",
    "isDeleted": 0
}

GET:/rest/books/:id/tags

[
    // ...
    {
        "id": "lV9joSBdzo",
        "name": "star wars",
        "isDeleted": 0
    },
    {
        "id": "YDWdgufb3a",
        "name": "best seller",
        "isDeleted": 0
    },
    // ...
]

What's The Problem?

The Homepage requires 31 HTTP GET requests to the API to populate the view.

Lots of data we do not require is returned.

Possible Solutions?

  • Extend RESTful API to return deep objects.
  • Expand App with Redux.
  • Expand with React Hooks useContext, useReducer.
  • Or get all the required information with one call using...

GraphQL Server

4 Keys Things to Know

  1. Schema
  2. Queries
  3. Mutations
  4. Scalars

Schema GQL

type Author {
    id: ID!
    name: String
}
type Book {
    id: ID!
    title: String
    authors: [Author]
}
type Query {
    book(id: ID!): Book
    books: [Book]
    author(id: ID!): Author
    authors: [Author]
}

rootValue / Resolvers

This is how we tell GraphQL how to get and manipulate data.

  • Query: Provides selection functionality to GraphQL
  • Mutations: Provides create/edit functionality to GraphQL
  • Scalars: Provides the ability to Extend new data types

Defining Resolvers

type Query { // Schema GQL
    book(id: ID!): Book
    books: [Book]
    author(id: ID!): Author
    authors: [Author]
}
const resolvers = { // Javascript GraphQL Config
    book: ({ id }) => bookService.getBook(id),
    books: () => bookService.getBooks(),
    author: ({ id }) => authorService.getAuthor(id),
    authors: () => authorService.getAuthors()
} // close resolvers

Resolvers must return all of the data defined in the schema.

Book Authors?

class Book {
    constructor(id) {
        return booksService.getItem(id).then((record) => {
            for (let [key, value] of Object.entries(record)) {
                this[key] = value;
            }
            return this;
        });
    } // close constructor
    authors() { /* return array of authors */ }
    static getList() {  /* return array of Books */  }
}; // close Book
const resolvers = {
    book: ({ id }) => new Book(id),
    books: () => Book.getList()
} // close resolvers

Hardcore Mode!

You can also manually define the schema and resolvers.

Covered in the Constructing Types Guide:

graphql.org/graphql-js/constructing-types

Requesting Data

POST:/graphQL

{
    books {
        id,
        title,
        authors {
            name
        }
    }
}

Recieving Data

{
    "data": {
        "books": [
            {
                "id": "Id3n0gB2SX",
                "title": "Mortal Engines #1: Mortal Engines",
                "authors": [
                    {
                        "name": "Philip Reeve"
                    }
                ]
            },
            // ...
        ]
    }
}

Putting it Together

Demo Time!

Resources

GraphQLgraphql.org
Getting Started with GraphQL & Node.Jsgraphql.org/graphql-js
GraphQL Cheat Sheetdevhints.io/graphql
Apolloapollographql.com
Prismawww.prisma.io
My Blogblog.christophervachon.com

Questions?

Christopher Vachon

Midland, Ontario

FullStack Developer

Beer Enthusiast and Home Brewer

Traveller

christophervachon.com

code@christophervachon.com

Christopher Vachon

Development Operations Manager

LabX Media Group

chrisv@labx.com

That's Right! We're Hiring!

  • Junior Web Developer
  • Web Developer
  • Systems Administrator

Thank You!

Christopher Vachon

Midland, Ontario

FullStack Developer

Beer Enthusiast and Home Brewer

Traveller

christophervachon.com

code@christophervachon.com

Christopher Vachon

Development Operations Manager

LabX Media Group

chrisv@labx.com

That's Right! We're Hiring!

  • Junior Web Developer
  • Web Developer
  • Systems Administrator
NorthOT