GraphQL, You're Intuitive and Flexible, We'll Be Friends

Eevis - Oct 29 '20 - - Dev Community

In May, I gave a talk in Futurice Tech Weeklies about my journey learning GraphQL. In this blog post, I will share the key points from the talk, and if you prefer watching/listening to the talk, you can find it as embed at the end of the post. A disclaimer: this is not a comprehensive guide to GraphQL. I've added some links to the end of the blog post for those who want to learn more.

Getting into a new language or technical concept can be compared to the process of getting to know a new person. There are five phases:

  1. First encounter
  2. Getting to know better
  3. The crush
  4. The conflict
  5. Getting over the conflict

For me, getting to know GraphQL was like this, and I'll share my journey through the steps.

First Encounter

When you first meet the person, you might recognize that the person seems interesting, and there even might (or might not) be sparks flying. You still don't know anything about the person, but maybe want to get to know them better.

My journey with GraphQL started in 2016, which was fairly early. GraphQL has been around since 2012, as it was developed and used internally at Facebook, but its public release was only in 2015.

It was a dark and stormy night (ok, this is just for the storytelling purposes) when I was browsing the internet and came across this website with the pink accent colour (https://graphql.org/learn looked pretty much the same as today). The contents seemed interesting, but I was still at the beginning of my learning to code -journey, and it all seemed too advanced. So it was not yet the time for our friendship to begin.

Getting to know better

In a friendship, the second phase is to get to know the person better. Maybe meeting with them (or communicating with them in different remote channels, as the social distancing continues) and learning about them.

The right time for me and GraphQL came about a year after the first encounter. I had started working as a software developer, and had learned the basic concepts about programming, and was ready to learn new things.

Maybe at this point, it would be beneficial to introduce GraphQL - what it actually is? Here's how GraphQL.org describes it: "GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data."

It has three actions, which are used for interacting with the data: Query, Mutation, and Subscription. You can think of queries as the concept of GET in HTTP requests. Mutations are like all the other verbs (POST, PUT, DELETE...)- they aim to mutate the data. Subscriptions are like WebSockets and actually use the WebSocket technology under the hood.

Some words should maybe be explained; GraphQL itself is not a server, nor a database. It is a query language. There are, however, libraries for GraphQL in many languages. These libraries provide the functionality to create servers and clients.

Being a JavaScript-developer, the examples I'm going to provide use syntax from the library called Apollo GraphQL and are written in JavaScript.

Some other terms worth mentioning are type definitions (or schema), and resolvers. They are used to define how GraphQL-API should work and what types it provides. Type definitions are, as the name states, the definitions of types. They could look like this:

type Poet {
  name: String!
  nationality: String!
  literatureMovement: String!
  poems: [Poem]!
  bornIn: Int!
  diedIn: Int!
}

type Query {
  poets: [Poet]
}
Enter fullscreen mode Exit fullscreen mode

Resolvers are functions that handle the actual data-fetching from, for example, the database. They resolve the requests sent to the server, and return correct data. Here's an example what a resolver could look like:

const resolvers = {
  Query: {
    poets: () => {
      // Here would be all the logic needed for actually 
      // getting the poets from the database. 
      // But for the sake of an example, 
      // we just return an array:
      return [{
        name: 'Anna Akhmatova',
        nationality: 'Russian / Soviet',
        literatureMovement: 'Acmeism',
        poems: [/* The poems would be here */],
        bornIn: 1889,
        diedIn: 1966
      }]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

If you want to learn more, I highly recommend checking out the resources at the end of the blog post.

The Crush

If there is a certain kind of chemistry between you and the new friend of yours, the next step is something I call "the crush". Don't get me wrong, this doesn't have to mean anything romantic - you just see the person as almost perfect and feel like it's good to be around them. You don't really notice all the flaws they might have.

I had that time with GraphQL. I believed GraphQL could be the answer to (almost) everything. Like, I almost believed that GraphQL could bring world peace. At the time, I was learning more and more things, and they all seemed perfect and without problems.

I'll introduce two things I found intriguing: the fact that with GraphQL, you can ask for the things you actually need and get them with just one query.

Get only things you actually need

Imagine a situation you would need only names of the poets to list them on a page. Alright, we have a REST-API with an endpoint /poets/. You request all the poets from there... and it returns them, with objects containing all the information about the poets. But you just needed the name. With GraphQL it is possible to ask for only the names of the poets:

query {
  poets {
    name
  }
}
Enter fullscreen mode Exit fullscreen mode

and what you would get is:

{
  "data": {
    "poets": [
      {
        "name": "Anna Akhmatova"
      },
      {
        "name": "Marina Tsvetaeva"
      },
      ...
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Get them with one query

So, with a pure REST-API, getting, for example, a poet with her poems could need few requests to the server. First, there would be a request to get the poet with something like /poets/:poet_id. But that's just the poet, not her poems. There should be another request to /poets/:poet_id/poems to get the poems too. With GraphQL, the process is more straightforward:

query {
  poet {
    name
    poems {
      title
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

The Conflict

In friendship or, any relationship for that matter, there's always a time when that crush fades out, and those little (or bigger) annoying things become noticeable. You realise that the person is not actually perfect.

For me, this time was one project that had rather complex data handling in the front end. If I had known in the beginning what I know now, the project would have been a piece of cake.

The biggest problem was the lack of documentation: We were using Apollo Client at the time for its state management capabilities, but documentation showed only rather simple examples. We needed more.

In the end, it all worked out pretty well, but the code was not beautiful. It displayed lots of layers of learning new things and mistakes made at the beginning of the project and some hacky-ish fixes. I learned a lot, but I also realised that maybe GraphQL won't bring world peace.

I must say this: Documentation on Apollo Client has evolved since that project, and I think version 3.0 has brought some features that could have helped us in the project. So I'm still a happy user of Apollo Client - it just isn't perfect (as technology never is).

As mentioned, I started to realise that GraphQL won't solve all of my problems. Some things are still in the works, and some things work differently from what a developer using REST would assume.

Two examples of these are N+1-problem and Error handling. There's a blogpost about the N+1 problem (and a solution to it) by Leonardo Losoviz. Also, for me, Sasha Solomon's talk at GraphQL Summit 2020 was an informative explanation for understanding error handling in GraphQL.

Getting Over the Conflict

If you decide that you can live with the imperfections and flaws that your friend has, then this is the point where the real friendship starts.

As I was hinting before, I got over the conflicts, and the friendship with GraphQL is still going strong. I keep learning and finding new cool things. As I've shifted to be more of a front-end developer, my learnings are mostly from the client-side of web applications; for example, the state management with Apollo Client (and especially with version 3.0) is something I'm excited about. Also, there are things like @rest-directive, which helps to fetch data also from REST-APIs by using GraphQL-client. How cool is that, right?

Some resources

The talk

Slides for the talk

Photo by 🇸🇮 Janko Ferlič on Unsplash

. . . . . . . . . . . . . . . . . . .