GraphQL : The hero we deserve (Part 2)

Shobhit Chittora
4 min readSep 16, 2018

--

If you landed directly here, it’s highly recommended to check out the Part 1 of this blog series. This will help you keep up with concepts in this part and have a better context altogether.

Okay! So by now, you should be convinced of choosing GraphQL as your tool of choice for your future API(s). But before you do that, it’s very important to know what you’re dealing with. So, this section introduces you to some of the very core concepts you need to build your next GraphQL client or server. Let’s begin!

Schema Definition Language ( SDL )

GraphQL provides its own language to write Schemas. It’s called the Schema Definition Language ( SDL ) or Interface Definition Language ( IDL ) by some. The SDL is a very simple and human-readable format to describe the entities in your system and also their properties. The SDL also comes loaded with a very powerful type system, to help you write Schemas with strong type definitions. Consider a snapshot of an SDL used for a Todo application.

type Todo{
id: ID!
title: String!
completed: Boolean
createdAt: DateTime!
}
type Todos{
todos: [Todo!]!
}

The above schema has two types: Todo and Todos, and also their respective fields. Each field has a type defined on it and is marked required by using ! . The type on a field can be a scalar type provided by the GraphQL spec (Int, String, Boolean, etc ) or any other custom type defined in your schema. For more details on the schema, head on the official doc.

READ data using Queries

When loading data from a GraphQL server, you just need to send your query written in your SDL to the endpoint exposed by the server. Note that there’s only one endpoint exposed by any GraphQL server to access all the data. This is done by having resolver functions for each type in your schema. Don’t get confused, resolver functions are just plain functions, written in the language of your choice, which get the data ( from a DB or an external API or just in-memory objects ) for your queries. Consider the example below —

// Queryquery {
allTodos{
id
title
completed
}
}
// Response{
"data": [
{id: 1, title: "Get some eggs!", completed: true},
{id: 2, title: "Read books", completed: true},
{id: 3, title: "Clean stuff", completed: false}
]
}
// Resolver ( in JS )
// For now this depicts usage of in-memory data
const todos = [
{id: 1, title: "Get some eggs!", completed: true} ,
...
];
const allTodos = () => {
return todos; // can be a db call or external API call
}

Notice how the query has a resolver with the same name which is executed whenever the clients fire the query. The resolver abstracts away the complexity of data interactions such as from your other micro-services or external APIs. Cool right! Another thing to note here is that fields you’re asking for in the query is called the selection set of the query and the queries can be nested too. Example —

query{
getUser(name: "John"){ <-- Root Query
id ---
name |
todos{ |-- Selection set
title |
completed |
} ---
}
}

On last thing to note about queries is that you can also have arguments to your queries. Consider the example below —

// Queryquery{
getTodo(id: 1){
id
title
completed
}
}

WRITE data using Mutations

We’ve seen how to do “READ” operations using queries, now we’ll see how cover ‘C’, ‘U’ and ‘D’ from the famous CRUD model. To perform create, update and delete operations in GraphQL, we use “Mutations”. Mutations are another type available in GraphQL which allows you to send queries and get the result of the operation back. Consider the following example —

// Mutationmutation{
addTodo(id: 4, title: "Write this blog!"){
id
title
}
}
// Response{
"data": {
id: 4,
title: "Write this blog!"
}
}

Mutations also have resolver functions backing them up to get the data from external and internal sources. There’s nothing much difference between a query and a mutation implementation wise.

REAL TIME updates using Subscriptions

Another great feature which GraphQL supports out of the box is real-time subscriptions. You can subscribe to create, update or delete events on your schema and give your user powerful features. Subscriptions use web sockets on the web to have a steady connection with the server. Whenever an event happens the server sends a stream of updated data over web-socket for the client to act upon. An example looks like this —

// Subscriptionsubscription{
addTodo{
id
title
completed
createdAt
}
}
// Response when a new Todo is added{
"data": {
id: 4,
title: "Write this blog!",
completed: false,
createdAt: "1537093485"
}
}

Recap

Schema is one of the most important concepts in GraphQL. You can have your custom schema types defined and use the reserved schema types like — query, mutation, and subscriptions, i.e., you have the below reserved for you —

type Query{}
type Mutation{}
type Subscription{}

You can use any of the queries as an entry point for your client request. Then you can then call a root query and define a selection set or any argument if any. And remember you can also deeply nest queries when you’ve complicated schema dependencies.

And that’s it! This has been a very brief brush over the core concepts of GraphQL. There are many topics like caching, security, etc, to consider before starting to implement your GraphQL clients and servers. You can refer to some of the resources below —

  1. https://github.com/chentsulin/awesome-graphql
  2. https://graphql.org/learn/
  3. https://www.howtographql.com/
  4. https://www.prisma.io/blog/

Thanks for reading and as always you can find me on —

Twitter — @shobhitchittora

Github — shobhitchittora

StackOverflow — shobhitchittora

LinkedIn — Shobhit Chittora

--

--

Shobhit Chittora

Full Stack JS Developer @PayPal, ❤️ JS , Open Sorcerer 💻, Seeker 🚀, …