GraphQL - What? Why? And How?

Published

July 25, 2019

According to Stack Overflow, GraphQL is part of the ‘hottest stack’ in the tech scene . It has continued to be adopted by many companies for the benefits it brings. It was developed by Facebook in 2012 to drive their large, complex social systems of billions of users. In this piece, we’ll discover what GraphQL is, the reasons to adopt it and how to implement it.

Graphql one end point

What is GraphQL?

In simple terms, GraphQL is a new way to fetch from an API. In other words, an alternative to REST. There are three main parts for GraphQL: Schema, Query and Resolvers.


Schema
The schema shows how to get the data and data type. To list, GraphQL schema has three types: Scalar types, Object types and Mutation type.

Scalar types Object types Mutation types
Int:
Float:
String:
Boolean:
ID (serialized as String): A unique identifier
type Typename {
fieldA: String
fieldB:Boolean
fieldC:Int
fieldD:CustomType }
type Query {
getBooks: [Book]
getAuthors:[Author]
}


PUT,
POST,
PATCH,
DELETE

More schema details can be found in GraphQL schema concepts.


Query
Queries in GraphQL are analogous to REST’s GET. In particular, they allow us to ask the server for the data we need.

type Query {
   info: String!
   Feed: [Link!]!
}

type Link {
   id: ID!
   description: String!
   url: String!
}


Resolvers
A resolver is a function that resolves a value for a type or field in a schema. Certainly, it is the most difficult part of GraphQL. To illustrate, a resolver example from Prisma shows below:

const UserType = new GraphQLObjectType {
   name: ‘User’,
   fields: {
     id: {
       type: GraphQLID,
       resolve: (root, args, context, info) =>  {
        Return root.id
       }
     }
   },
   name: {
     type: GraphQLString,
     resolve: (root, args, context, info) =>  {
       Return root.name
     }
   }
}

Why do we use GraphQL?

In short, we use it for three main reasons:

  1. Network performance
  2. Clean endpoint design
  3. To serve multiple clients.


1. Network performance
With GraphQL we only get what we need to prevent data transfer waste.
For example, we need a person’s full name. When we use Rest API to get a user name, we are getting the user name with seven additional fields. In contrast, GraphQL can fetch just the two fields that make up the user name.

Rest get:

user: {
       Id:
       firstName:
       lastName:
       email:
       address:
       createDate:
       updateDate:
       application:
       disable:
      }

GraphQL get:

query {
  users {
    firstName
    lastName
  }
}


2. Clean endpoint design
With GraphQL, we can create a single endpoint to cover the concept of a person.

For instance, a REST endpoint example:


GET /person
GET /person/:id
GET /person/:id/tasks
GET /person/:id/projects
GET /person/:id/projects?include=tasks
GET /projects?userId=:id&include=tasks

REST creates six endpoints, contrarily, a GraphQL one endpoint with query example:

{
  person(id: 1) {
    projects {
      name
      tasks {
        description
      }
    }
  }
}


3. Serve multi clients
When we build a site for web, mobile, tablet or TV client etc, we can enable the backend to return a different json structure with REST. We normally create a new custom endpoint (e.g /mobile) with a custom representation such as (Content-Type: application/vnd.rest-app-example.com+v1+mobile+json), and a different response structure. Certainly, all of this requires back-end work. For example: Netflix API.

With GraphQL, the client can build complex requests up on demand without any changes on the backend.

Web client example:

{
  person(id: 1) {
    projects {
      name
      Date
      tasks {
        description {
          name
          date
        }
      }
    }
  }

Mobile client example:

{
  person(id: 1) {
      firstName
      lastName
  }
}
{
  project(personId: 1) {
      name
      date
  }
}

How to write GraphQL?

There are many GraphQL frameworks. AppSync, Firebase, Hasura and Prisma are the most popular ones.

I have experimented GraphQL with both Prisma and AWS AppSync.

Prisma

1. Installation

npm -g install prisma


2. Create project

mkdir prisma-project-name 
cd prisma-project-name


3. Set up local Prisma server

Prisma init

* Docker needs to be installed for Prisma local development

Configurations shows below:

Prisma set up configuration


4. Start Prisma

docker-compose up -d


5. Deploy a service to the local cluster

prisma deploy

Prismas generated files shows below:

Prisma generated files


Local GraphQL playground can be found at http://localhost:4466

local graphql playground


6. Deploy the local server to cloud

Update endpoint in prisma.yml


AppSync

AWS AppSync is AWS GraphQL service. In particular, it is best for cloud based infrastructure development. GraphQL API can be created through AWS console I have used AWS amplify to create it.

AWS Account is needed for using AppSync.

1. Installation

npm i -g @aws-amplify/cli

2. Create project

mkdir aws-graphql 
cd aws-graphql

3. Initialise the AWS Amplify project

amplify init

With below configuration:

AWS Appsync set up configuration


4. Create graphQLAPI

amplify add api
AWS AppSync api configuration set up


5. Edit graphql schema
schema.graphql has been generated under
amplify-app/amplify/backend/api/amplifygraphql/schema.graphql

6. Generate resolvers

amplify push
AWS AppSync push configuration


When it is finished, log into AWS console, search for AppSync, GraphQL playground can be found under Queries:


7. Local development

AppSync local development documentation is limited. I have tried with AWS serverless.

npm install -g serverless

A few plugins are needed for offline development.

npm install serverless-offline serverless-dynamodb-local serverless-appsync-offline --save-dev

Add serverless.yml on project root if it is not there already, add the plugins to the plugins section.

plugins:
- serverless-dynamodb-local
- serverless-appsync-plugin
- serverless-appsync-offline
- serverless-offline

Install DynamoDB-Local

serverless dynamodb install --localPath ./bin

Update the configuration in serverless.yml for appsync-offline

custom:
  ...
  appsync-offline: # appsync-offline configuration
    port: 62222
    dynamodb:
      client:
        endpoint: "http://localhost:8000"

Launch the Offline server

serverless offline start

If you have issue with dynamodb, this is the fix ( there is an issue with latest serverless-dynamodb-local)

npm install serverless-dynamodb-local@0.2.35
sls dynamodb install --loclPath ./bin

However, serverless offline can only access the graphQL endpoint with local dynamodb. It will not generate resolvers after updating graphQL schema, so it is not ideal for local development.

To summarise

Prisma
Pro's:

  • Easy to get started
  • Tooling and community are good
  • Good documentation
  • Auto generated ORM (Object-Relational Mapping) connect to database
  • Easy to migrate from local server to cloud

Con's:

  • Error messages can be ambiguous
  • Inefficient data structures
  • Learning curve to write graphQL resolver
  • Inflexible migration


AppSync
Pro's:

  • Good integration with AWS ecosystem
  • Good tooling for cloud based development
  • Easy to start with AWS amplify
  • Offline data synchronization

Con's:

  • Limited Local development support
  • Learning curve to write graphQL resolver in VTL (Apache Velocity Template Language )
  • Requires infrastructure for big team development

What should we use?

In conclusion, AppSync is Backends-as-a-Service (basically "Firebase for GraphQL"). It indeed gives a GraphQL CRUD API instant with authentication/authorization function and database connection. It is certainly great for simple applications. However, for an enterprise project when requirements become more complex, large development teams can quickly outgrow the capabilities of a BaaS. Whereas Prisma provides more control and flexibility in technology stack. In addition, GraphQL was invented as a query language for APIs, not a database. Clients should still be able to consume a domain-specific API that is tailored to their needs.

Are you interested in becoming a SR. Frontend Developer at WORTH in our UK office? Check out the vacancy here and we might welcome you to the team soon!

Get in touch

We'd love to
hear from you

This field is required
This field is requiredThe email address is invalid.
You must consent to the Privacy Policy

Thank you

We will get back to you as soon as we can.