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.

Write Custom GraphQL Server
Write Custom GraphQL Server

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)

graphql-js

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)

graphene

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)

graphql-go

Authorization

Custom

Caching

Data Loader batching only

Code Generator

Yes, with graphql-code-generator

Clients

shurcooL/graphql

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)

graphql-ruby

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)

graphql-java

Authorization

Field level visibility

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.

Hot Chocolate GraphQL Platform
Hot Chocolate GraphQL Platform

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)

graphql-dotnet and Hot Chocolate

Authorization

Yes, role based, @authorized directive

Caching

Data Loader batching and caching, document based caching

Code Generator

Yes, with graphql-code-generator

Clients

graphql-client

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?

Blog
19 Oct, 2021
Email
Subscribe to stay up-to-date on all things Hasura. One newsletter, once a month.
Loading...
v3-pattern
Accelerate development and data access with radically reduced complexity.