Top ways to write a custom GraphQL Server with production ready features
GraphQL has evolved over the years and now has wide support in the community across languages and frameworks. Open source implementations of the GraphQL spec are now available in most popular languages. In this post we will look at the most popular libraries for each language for anyone to get started with and ways to add production ready features like Authorization, Rate Limiting, Caching etc.
The common interface to try out GraphQL requests can be GraphiQL, irrespective of how your API is built. If you are looking to test your GraphQL APIs, here is the list of GraphQL IDEs that you can try out.
The GraphQL runtimes mentioned in each of the languages are spec compliant and in some cases even have draft implementations of newer spec that is work in progress.
Node + GraphQL
Lets start with the origins. The original implementation of GraphQL spec was written in Node.js by the Facebook team and it was released as a reference implementation graphql-js.
This was followed by various GraphQL runtime implementations by the community in other languages. But JavaScript community has had the most number of projects, both client side and server side.
GraphQL Runtime(s) | |
Authorization | Yes, with graphql-shield module |
Caching | Response caching with envelop response-cache plugin |
Code Generator | Yes, with graphql-code-generator |
Clients | @apollo/client, urql and more* |
Subscriptions | graphql-subscriptions module (Pub/Sub) - graphql-ws |
Relay Support | Yes, can be added with graphql-relay-js |
Rate Limiting | Yes, with graphql-rate-limit module |
Tracing | Yes, with apollo-tracing extension |
*If you are curious on the clients, here is a great resource to check out fluent graphql clients.
Note that, this may not be a comprehensive list of modules available for each feature implementation. Do let us know in the comments, if you feel there are other modules or plugins which might be more suited for specific use cases.
There are many server implementations which add more value on top of graphql-js. Ben Awad had done a nice benchmark suite to test the performance of different Node based GraphQL runtimes.
Python + GraphQL
Python has a few options in the GraphQL space. Whether you are building a full fledged app using Django or just building a GraphQL server from scratch, you got it covered.
GraphQL Runtime(s) | |
Authorization | Limiting field access, Global filtering |
Caching | Data Loader batching and caching* |
Code Generator | NA |
Clients | gql, python-graphql-client |
Subscriptions | Yes, Django channels with graphql-ws |
Relay Support | Yes, with graphql-relay-py |
Rate Limiting | Using django rate limit configuration |
Tracing | NA / Custom |
The graphene framework gives you a headstart but if you are using the django integration, then you can add features like rate limiting more easily. graphql-code-generator doesn't seem to support Python yet and it looks like code gen is lacking.
On the client side, there's one maintained by Prisma, which is the python-graphql-client.
Golang + GraphQL
The reference implementation for GraphQL on Golang is available at graphql-go/graphql. It supports queries, mutations and subscriptions and is spec compliant as it follows the graphql-js implementation.
GraphQL Runtime(s) | |
Authorization | Custom |
Caching | Data Loader batching only |
Code Generator | Yes, with graphql-code-generator |
Clients | |
Subscriptions | Yes |
Relay Support | Yes, with graphql-relay-go |
Rate Limiting | NA / Custom |
Tracing | Yes, with graphql-go |
Now this list can be extended to other languages and frameworks like PHP, Haskell, Scala etc. Let me know in the comments if you want them to be added to this list.
One thing which seems to be clear is, you can get started with a spec compliant runtime or an enriched framework but there are certain production ready features that require adding plugins.
Ruby + GraphQL
The Ruby implementation of GraphQL is open-source at graphql-ruby which is widely used in enterprises like GitHub and Shopify.
You can install it by adding the graphql
gem to your gemfile.
If you are looking at Authentication with JWT, you can check out the graphql-auth gem.
GraphQL Runtime(s) | |
Authorization | Yes, with graphql.pro plugin(paid), |
Caching | Resolver level caching with graphql-cache plugin |
Code Generator | Yes, with generators |
Clients | graphql-client by GitHub and graphql-ruby-client |
Subscriptions | Yes with graphql.pro plugin (pusher) |
Relay Support | Custom |
Rate Limiting | Yes, with graph_attack gem |
Tracing | Yes, with graphql tracing module and apollo-tracing extension |
Java + GraphQL
The reference implementation for GraphQL in Java is available at graphql-java.
There's a more full fledged framework called the DGS Framework, built by the folks at Netflix that has more production ready modules ready to be added to the GraphQL server.
GraphQL Runtime(s) | |
Authorization | |
Caching | Query caching with java-dataloader |
Code Generator | Yes, with graphql-code-generator |
Clients | GraphQL Java Client DGS Framework |
Subscriptions | Yes, reactive streams with RxJava |
Relay Support | Custom |
Rate Limiting | Query Depth Limiting available |
Tracing | Instrumentation with DGS Framework |
If you are looking for more awesome resources to get started with Java and GraphQL, check out this awesome-graphql-java list.
.NET + GraphQL
If you are in the Microsoft .NET platform, the open source GraphQL server Hot Chocolate is the go to choice. It is much more than just a reference implementation as it gives you the ability to build a GraphQL Gateway for a federated data graph.
You can use the Hot Chocolate server as a standalone ASP.NET Core Server or as a Serverless Azure Function that serves a GraphQL endpoint.
The serverless support opens up use cases where you can build event driven applications using the 3factor app architecture.
GraphQL Runtime(s) | |
Authorization | Yes, role based, @authorized directive |
Caching | Data Loader batching and caching, document based caching |
Code Generator | Yes, with graphql-code-generator |
Clients | |
Subscriptions | Yes, through the use of IObservable |
Relay Support | Yes, with relay toolset |
Rate Limiting | Built-in with graphql-dotnet and Hotchocolate |
Tracing | Yes, with apollo-tracing |
Add custom GraphQL to Hasura
Any of the above custom servers, (or any GraphQL endpoint) can be added to Hasura via Remote Schema. All you need is an endpoint and the relevant auth headers to be able to aggregate these types into Hasura. This lets you query your custom GraphQL API from your frontend client via Hasura's unified API endpoint.
Authorization
When it comes to security, especially Authorization for your API, you need to add more plugins on top of these servers.
Some of them are role based, some provide field level filtering etc. There are naunces here to understand what the plugin offers. But by far, graphql-shield in the Node.js ecosystem seems to offer a more rounded set of features for adding Authorization to a GraphQL server.
Relationships between Data
Extending your custom server to interact with other GraphQL servers is going to be critical since modern apps require data aggregated from various places and some of which are related.
Some frameworks in the above list support schema stitching to aggregate different GraphQL schemas. A few support federated style where you can establish relationships between different types and schemas.
Hasura for existing GraphQL APIs
If you are looking to leverage Hasura for all your existing APIs and need features like Authorization, Caching, Rate Limiting, Monitoring and Analytics, then check out this guide - Hasura for existing GraphQL APIs
Most of the above servers are reference implementations of the spec with added nicety to make it easy to start writing code. This boilerplate doesn't necessarily involve features like Authorization, Caching, Monitoring out of the box. Mostly it is restricted to defining the GraphQL schema and custom types associated for your API with the right resolvers for the same.
You will need different plugins for each production ready use case and wire it up all together to run a production ready GraphQL API. As the community evolves, we will see more matured solutions in all languages for a lot of these features.
Do let us know in the comments - What's your go to language / framework for writing a custom GraphQL server?