Github is a service I respect and depend on so its adoption of GraphQL for an update to their API pushed me to look into GraphQL.
- For the server side I settled on graphql-java.
I also decided to follow the generally accepted wisdom that you only tackle the data management parts of your API with GraphQL, and leave things like authentication as they were.
The graphql-java package came with some good examples that let me start trying it out right away. But the service I was migrating was based on tools that didn’t exactly line up with their examples so it wasn’t plug and play. My service was written with Spark: “A micro framework for creating web applications in Java 8 with minimal effort.” And as it turned out connecting graphql-java to Spark was straight forward. Associate something like the following with the graphql HTTP POST path:
And your service can now dispatch GraphQL requests in JSON of the form:
With that dispatcher in place you can start the process of working on your GraphQL schema implementation, where the magic takes place.
The GraphQL Schema
The schema, at least in graphql-java, is where a lot of the work starts and ends. In a RESTful service, you tend to map a single HTTP request path and operation to a specific Java method. With graphql-java the schema is a holistic description of types, requests, and how to fulfill them. It almost has the feel of a Guice module, or a Spring XML configuration. There are tools designed to simplify schema creation, but since I had set out to learn GraphQL I decided to feel the pain and create the schema by hand. Every type exposed by the API had to be described. Every request had to be described. The associations between the requests and the code fulfilling them had to be described. Again the graphql-java examples and tests proved a good resource but nothing there was a drop in solution.
Describing an Entity
The service I ported was a snippets app. One of of its domain classes is a way to categorize a snippet:
To add this class the the GraphQL schema you have to fully describe it:
Queries and Mutations
Once you’ve described the classes, you need to describe how you’ll retrieve instances, here’s an example of retrieving by key, and retrieving them all:
To create, update or delete objects you’ll need to define the “mutations”, here’s my category create:
From these samples you can tell that the schema is, as the name implies, a detailed description of the classes and operations on them. The format is verbose, but I found I pretty quickly picked up the syntax and semantics and developing the complete schema wasn’t too bad a chore. Also, don’t forget there we tools claiming to ease the process that might be useful.
My Conclusions from the Experience
So with a couple days of learning and coding I got my snippets service moved from RESTful to GraphQL API. What are my initial observations?
- The work is in the schema. I’ll be looking at the tools to help there in my next refactoring.
- Both the server and the client benefitted from GraphQL’s more holistic approach. Where GraphQL had a single schema, dispatcher and client pattern, RESTful had used GET/POST/DELETE methods each somewhat distinct.
- The performance suffered a bit. I’ve done a lot or RESTful services, and this was my first foray into GraphQL so I’m not surprised that it wasn’t quite as quick end to end. I’m suspicious of some of the magic (likely reflection based) that graphql-java uses to execute the schema queries. That said I’m betting I can improve the performance by doing some things better then my first attempt.
But overall I liked the GraphQL experience and will probably advocate it over RESTful going forward.
As always the complete code for my work is in github.