Beginner's Guide To GraphQL

Published on October 18, 2022

GraphQL and REST are two ways of building APIs (Application Programming Interfaces) that allow clients to access data from a server. REST has been around for a while, and most developers are familiar with it. The REST concept is relatively very easy to understand - it uses a fixed set of endpoints for clients to interact with the server. On the other hand, GraphQL is a newer technology, developed by Meta. Its concept is very different from REST so getting started and putting to rest😏 the REST mindset can be a bit scary. In a nutshell, GraphQL lets clients request specific data by writing a query. This makes it more flexible and efficient compared to REST.

GraphQL vs REST

Below are the fundamental differences between GraphQL and REST API:

Feature GraphQL REST
Data Retrieval Client can request specific/dynamic data by specifying the fields it wants in a query Client can only access fixed data through a fixed set of endpoints provided by the server e.g. `/authors`, `/author/:id`, `/books`
Protocol Uses a single HTTP verb: POST for all server actions Uses a variety of HTTP verbs - GET, POST, PUT, and DELETE, to perform different actions on the server
Flexibility The client can request exactly the data it needs in a single request, reducing the need for multiple API calls Client has to make multiple API requests to get data from an API due to *under-fetching
Data aggregation Allows clients to request data from multiple sources in a single request, making it easier to aggregate data from multiple sources Each data source typically has its own endpoint, so the client must make multiple requests to get data from multiple sources
Versioning GraphQL allows the server to add new fields and types to the API without requiring the client to update its request Versioning is common and is typically handled by creating new endpoints for each new version of the API
* over-fetching occurs when the client receives more data than it needs
* under-fetching occurs when the client needs to make multiple requests to get all the data it needs

Schemas and Queries

A schema is the heart of GraphQL. It defines a collection of types, which represent the different kinds of data that can be accessed through the GraphQL API, and the relationships between those types.

Types can be one of the GraphQL’s built-in scalar types: Int, String, Float, ID, or Boolean., or a custom object type e.g. the books field on type Author :

GraphQL checks each request using the schema to make sure it’s valid and then returns the data in the right way.

Object Types

Below are some object types. They are a specific type that shape the data for a particuar entity or resource:

type Book {
   title: String!
   subtitle: String
   author: Author!
}

type Author{
   name: String!
   bookCount: Int!
   age: Int
   books: [Book!]!
}

Object types define a special kind of data structure similar to a database model in object-oriented programming. The Book type above would be represented as follows in Django:

class Book(models.Model):
    title=Model.CharField(null=false)
    subtitle=Model.CharField(null=True, Bank=True)
    author=Model.ForeignKey(...)

Each field in the object type specifies what type of data will be returned for it.

 type Author {
    name: String!
    bookCount: Int!
    age: Int
    books: [Book!]!
 }

In the type Author, all fields must have a value except age, as shown by the exclammation marks. An exclammation mark indicates that field is not nullable. The books field will return a list of Book objects.

Query Types

Queries allow you to fetch data from the server.

type Query {
    books: [Book]
    authors: [Auhtor]
}

This query defines two fields, each returning a list of its corresponding type.

With GraphQL, these two resources are fetched with one query whereas in REST API, two HTTP requests would have been sent to `/api/books` and `/api/authors`.

With the above query type, we could execute the following query to fetch data:

query {
  books {
    title
    author {
      name
    }
  }
  authors {
    name
  }
}

Because the query field books returns a list of Book objects, we must define what fields to return for each book: title and author's name.

The query returns all requested fields as long as they were defined in the schema’s query type.

Arguments

In GraphQL, it is possible to pass arguments to a query to help filter or shape the data that is returned.

Arguments are values that are passed in a query field along with the field name, and must have a defined type, which can be any of the built-in scalar types (such as String, Int, Boolean, etc.) or a custom object type defined in the schema.

They must also be named, so that they can be referenced in the query:

// schema
type Query {
  findBook(title: String!): Book
}

// query
query {
  findBook(title: "Outliers") {
    subtitle
    author {
      name
      age
    }
  }
}

In this example, the title argument is used to filter books. The server will return only the book with a title of Outliers, and the returned data will include subtitle, and the associated author’s name and age

Enums

In GraphQL, an enum is a type that defined a set of values. They are used to represent a fixed set of options that a field can take on:

enum BookFormat {
    EBOOK
    HARDCOVER
    PAPERBACK
}

type Book {
    title: String!
    author: String
    format: BookFormat
}

The enum BookFormat has three named values: EBOOK, HARDCOVER, and PAPERBACK. The Book type has a field called format whose type is BookFormat. THis means this field can only contain one of the three values. The enum can be used to query the books data:

query {
  books(format: HARDCOVER) {
    title
    author
  }
}

Mutations

While queries are used to retrieve data from a server, mutations are used to modify data. In GraphQL, mutations are operations that cause changes on the server-side, such as creating, updating, or deleting data.They are defined with type Mutation:

type Mutation {
  addBook(title: String!, author: String, published: Int): Book
}

in the mutation, the details of the operation are passed as parameters. The mutation has a return value, and in this case of type Book. If the operation is successful an object of type Book is returned,if it fails null is returned.

To add a new book, the mutation would look as follows:

mutation {
  addBook(title: "The Color Purple", author: "Alice Walker", published: 1985) {
    id
    title
    author {
      name
    }
    published
  }
}

Conclusion

GraphQL is a powerful and flexible query langage that allows clients to request the exact data they need from a server. It is also a great tool for building efficient and scalable APIs that evolve with the business needs. Next, read all about mutations in GraphQL