GraphQL: Love at second sight
By: Yanko Valera
Tags: Apollo Client, GraphQL, Apollo Server, Programming, API

My first project with GraphQL was a couple of years ago. I was working as a contractor, and my role was to develop a React responsive website, with a bit of exposure to the backend API. It was a few month’s projects, and I didn’t learn a lot about GraphQL / Apollo Client. At that time, GraphQL didn’t impress me a lot, and never used it again until last year.

Last year, I joined Clevertech. I started working on a project using GraphQL with Apollo (Server / Client). The first weeks were hard, but this time GraphQL and the ecosystem impressed me a lot.

For many years, I have been using REST to develop APIs. So, coming from a different background, why GraphQL captured my attention the second time?

First: the possibility to define API operations in the GraphQL Schema. The Schema defines the possible Queries (for requesting data), Mutations (for modifying), and types for inputs and responses. The client apps will know without any external documentation which Queries / Mutations should use, what is the expected input, the responses, which fields they can ask, get, etc. When a client executes a Query or Mutation, the GraphQL server will validate the client request against the defined Schema, and it will fail if it’s requesting an invalid field, or calling a missing / wrong Query / Mutation.

Second: the clients (mobile apps, web apps, etc.) can ask what they need and will get exactly that. It is one of the major benefits of GraphQL: the GraphQL server will execute and return only what the clients asked, no less, no more. This is good not only client-side, but also the server will only fetch, process and return what the client needs and only that.

For example, our Users / ChatMessage Schema can be like this:

type Query {

users: [User]

} type User {

id: ID!

name: String!

email: String!

receivedMessages: [ChatMessage]!

sentMessages: [ChatMessage]!

} type ChatMessage {

id: ID!

text: String!

sender: User!

recipient: User!

}

Imagine a mobile App calling a users Query, but only needing two fields:

{

query {

users {

id

name

}

}

}

An Admin website could call the same users Query and ask more information, for example, id, name, email, and the receivedMessage with information about the sender:

{

query {

users {

id

name

email

receivedMessages {

id

text

sender {

id

name

}

}

}

}

}

This feature helps to solve the problem where several clients are accessing the same API and need different information. With GraphQL, we will not have over-fetching or under-fetching. Also, it can get more resources in a single request: will get a list of users, and for each user a list of messages, and for each User, the sender.

Third: API versioning. This can be hard in a REST APIs, usually developers end of adding ‘v1’, ‘v2’, etc. because otherwise we can have breaking changes in the API. In GraphQL, we can just add new types and new fields to existing types without creating breaking changes.

Last but not least, the ecosystem. By using Apollo Client on the web and mobile applications, I was able to have a great developer experience and increased productivity. Apollo Client supports out of the box: Querying for data, Mutating data, State Management, and Caching. After many years dealing with different tools for state management, network access, caching, etc. this is one of the great benefits I have found so far.

I’m very excited about GraphQL, Apollo Server / Client, but as with every tool, it could add some problems and challenges in our daily work. In the next posts, I will be talking about some hard-learned features like Schema design, the N+1 problem, and other issues I have been finding along the way.