GraphQL is a remarkable tool to build APIs. However, it is quite different from REST. This can make it difficult for developers who have been accustomed to working with REST. There are some core concepts of GraphQL that are important to understand how GraphQL actually works.

We will be covering those core concepts in this post. However, if you are completely new to GraphQL, you should start with our Introduction to GraphQL and then, return to this post.

1 – Schema Definition Language (SDL)

GraphQL has its own type system. This system is used to define the schema of an API. Basically, the syntax for writing schemas is known as Schema Definition Language or SDL.

Let us see how a schema looks like:

type Author {
   name: String!
   country: Int!
}

This schema has two fields – the name of the author and the country. Both of these fields are of type String. The ! mark signifies that these are mandatory fields.

We can also express relationships between types. For example, an author can write a book. We can describe this relation as below:

type Book {
   title: String!
   publishYear: Int!
   author: Author!
}

We can also place the other side of the relation as follows:

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

Basically, this is a one-to-many relationship between author and book. Here, books field is an array of books.

2 – Queries

Queries are one of the fundamental reasons of using GraphQL. At its core, GraphQL is a query language.

In REST API, we fetch data from specific endpoints. Each endpoint has a particular structure. In other words, the client needs to adhere to the API structure. Basically, the request URL determines the query parameters in a REST API.

However, GraphQL has a considerably different approach. Instead of multiple endpoints, a GraphQL server typically exposes only one endpoint. The structure of the response is not fixed. Instead, it is quite flexible. Basically, the client specifies what data is required and the server responds with the required data.

This means that the client needs to send more information to the server. This information is nothing but the query.

Let’s look at a simple example of query:

{
  allBooks {
    title
  }
}

Here, allBooks is the root part of the query. What follows root is the payload of the query. In this particular example, we only specify a single field i.e. title.

The query will return something as below:

{
  "allBooks": [
    { "title": "Eye of the World" },
    { "title": "The Way of Kings" },
    { "title": "The Mistborn" }
  ]
}

Each book only has the title field in the response even though there might be more fields in the schema definition.

In case we want to fetch more fields, we can tweak our query as below:

{
  allBooks {
    title
    publishYear
  }
}

Here, we also added publishYear in the query.

GraphQL also supports hierarchical queries. For example, if we wish to also query books along with the author, we can describe the same structure in the query.

{
  allAuthors {
    name
    books {
      title
    }
  }
}

With this simple tweak, the GraphQL server will make sure to return author information along with the books written by that author.

3 – Mutations

While queries are great, we also need to update information using APIs. GraphQL supports updating data using the concept of mutations. We can create, update as well as delete data using mutations.

Mutations also follow a similar structure as queries. However, the only difference is the use of mutation keyword.

Let’s take a simple example of creating a new author.

mutation {
  createAuthor(name: 'Brandon Sanderson', country: "USA") {
    name
    country
  }
}

A mutation also has a root field. Here, the root field is createAuthor. This field takes two arguments – the name of the author and the country. Just like with query, we can also ask for return parameters. In our case, we are asking for the name and country. Basically, after successful execution of the mutation, the server will return the output with the name and country of the newly created author.

We can also ask the server to return an id in case we have an id field in the schema. See below:

mutation {
  createAuthor(name: 'Brandon Sanderson', country: "USA") {
    id
  }
}

4 – Subscriptions

Another one of the important GraphQL Core Concepts is around the topic of subscriptions. In many modern application, it is important to have a real-time connection between server and client so that the client can be immediately informed about important events.

Subscriptions don’t follow the typical request-response cycle. When a client subscribes to an event, it will hold the connection. When the particular event occurs, the server pushes the data to the client.

Subscriptions are also written using the same format as queries and mutations. See below example:

subscription {
  newAuthor {
    name
    country
  }
}

Once the client sends the above subscription request to the server, a connection is opened between them. Whenever a new mutation happens that creates a new author, the server sends information to the client as below:

{
  "newAuthor": {
    "name": "Robert Jordan",
    "country": "USA"
  }
}

Conclusion

As you can see, we have successfully gone through the Core Concepts of GraphQL. We understood the concept of Schema and how your clients can interact with GraphQL server using queries, mutations and subscriptions.

In case you are planning to build a GraphQL application, you can check out this post about GraphQL Architectural Patterns.

To get started with GraphQL, please refer to the next post about creating a GraphQL server using GraphQL.js.

If you have any comments or queries about this post, please mention them in the comments section below.

Categories: BlogGraphQL

Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *