Learning: GraphQL

Hi all,

Next up in my series without a good name but something like ‘what I’ve been learning’ is GraphQL.

GraphQL is something we use internally at my current employer and it was new to me upon joining. I’d heard of it, new there was a bit of hype around it, and have (spoilers) turned out to quite like it.

Rewind to January 2019, Sam and his naive mind thought RESTful services were the best and probably the only way to transfer data ever. Hmmm. Well, that’s somewhat changed.

GraphQL, in short lets you define a query in the shape of a graph (think abstract data type, not a bar chart), and from there, you can pluck the entities and their fields you want, rather than what the developer creating the API. I think of it as a platter of data and you can pick what you want rather than a set menu. A single query (request) may span multiple entities, or types, something you’d have to do with multiple requests back in REST days.

GraphQL isn’t a tool, it’s a language, and if you’re able to conform to it, you can use libraries and tools to interact with it. Our implementation queries our underlying SQLServer database (and a few other services) and even has a cache built on Redis. But since it confirms to the GraphQL spec, you can use it as database without reasoning about its implementation (and I often don’t! :P).

As I understand it, GraphQL also supports mutations alongside queries, which would let you change data. We’ve not done that yet, so I can speak to how good it would be, but it would be nice to get that benefit of a single point of read/write for multiple possible data sources. The idea of an abstracted but mutable source of truth is very appealing.

One downside I see to it is type safety and nullability of data at runtime. Say if I take a simple query like

user(id: ‘1’) {
  firstName
  email
}

But I have an interface in TypeScript (see last post) that also suggest there will be a lastName, but my query didn’t ask for it, at compile-time, the code accessing lastName will be fine, but at runtime, you’ll get unexpected behaviour. I’m not sure of a solution to this yet, but I imagine someone has created a library that works backwards from what you use and generates the queries for you. 

The most “fun” I’ve had with GraphQL so far is building a query generator. The use case was for a reporting service (spits out CSVs) and I wanted to make a flexible config format where you could say what columns you wanted to have. Each column required a certain graphQL query. I didn’t want to make multiple calls, so I had to find a way to merge queries (and their various child queries and grandchild queries and so on). I ended up using...well, a graph(more accurately a tree),  to represent the query, and then I was able to merge branches recursively and generate the final query by doing a depth-first traversal. Hey, look, that CS degree does come in handy!

Overall GraphQL seems a lot of fun. I don’t think it is an ‘always’ replacement for REST, but I think when you’re often exploring the relationships of data, it can save a lot of time. I note that GitHub’s new API is a GraphQL API, which makes sense to me. However, I’m sure there are more thorough posts to read about the pros and cons of GraphQL because this isn’t intending to be one. Just my initial thoughts.

‘Til next time!

Sam