Building GraphQL Servers with Subscriptions in Go

At Functional Foundry, we are very excited about GraphQL. Today, we’re releasing an open source library for implementing server-side subscriptions in Go using WebSockets.

Jannis Pohlmann
Functional Foundry
3 min readDec 14, 2017

--

GraphQL provides a flexible and efficient way to query data from servers. It is becoming a popular technology for designing backends, often replacing or wrapping somewhat inflexible REST APIs and putting clients in charge of deciding what data they need. There are a variety of libraries and frameworks out there for writing GraphQL clients and servers in JavaScript today, most notably Apollo and Graphcool. The Apollo team has also developed a protocol for GraphQL over WebSockets, which is primarily used for subscriptions in Apollo Client and Graphcool.

While JavaScript developers have all the tools they need to create GraphQL backends without friction, the Go ecosystem has so far been lacking support for GraphQL subscriptions. The excellent graphql-go project provides the two main building blocks for Go-based GraphQL servers: graphql-go/graphql (providing ways to parse and validate GraphQL schemas and documents, define GraphQL schemas and implementing field resolvers) and graphql-go/handler (providing a handler to serve a GraphQL schema over HTTP and handle incoming requests with queries and mutations). Together, both libraries provide almost everything developers need to stand up a GraphQL server. Apart from subscriptions.

Introducing graphqlws

Today, we’re open-sourcing a new Go library to fill this gap: graphqlws. It serves a simple purpose:

  1. implement the GraphQL over WebSocket protocol (used by all popular GraphQL clients) so you don’t have to,
  2. integrate seamlessly with net/http, and
  3. provide a simple way to access established subscriptions, perform authentication, and send updates to the corresponding clients.

You can find it on GitHub at https://github.com/functionalfoundry/graphqlws.

Step 1 — Basic Setup

Setting up a GraphQL over WebSocket endpoint with graphqlws is easy. Create a GraphQL schema, create a subscription manager, create an HTTP handler for the communication over WebSockets, then serve the handler using net/http. Optionally, you can define a function to authenticate users (the Apollo Client sends an optional authToken along with the initial WebSocket message when establishing a new connection; this function allows to resolve the token string into a user).

Setting up a GraphQL over WebSocket endpoint with graphqlws

Step 2 — Working With Subscriptions

The graphqlws library by itself merely implements the GraphQL over WebSocket protocol. It does not implement any subscriptions out of the box. A typical server implementation would listen to a database for changes and react to these changes by identifying which subscriptions need to be updated, re-executing the queries of these subscriptions and send the results to the corresponding subscription clients.

The following code example shows how subscriptions can be retrieved from the subscription manager at any point. They are grouped by their connections. Each connection has a unique ID and, optionally, the user as returned by the Authenticate function described earlier.

Each subscription stores the subscription query (Query, Variables and OperationName) as well as other information that can be useful to identify what kind of data the subscription is for (e.g. Fields and Document).

Using Query, Variables and OperationName the query of a subscription can be re-executed whenever needed. The result can then be sent to the subscribing client via the SendData method, as shown in the code example below.

Working with subscriptions using graphqlws

Step 3 — Combine with graphql-go/handler

Using a GraphQL over WebSocket endpoint in combination with a regular GraphQL HTTP endpoint works just like with any other net/http handlers. All you need to do is create two handlers and serve them via different routes. The following code example demonstrates this.

Combining graphqlws with graphql-go/handler

Summary

If you have made it this far, you are probably interested in using Go for your own GraphQL server. With graphqlws, server-side GraphQL subscriptions can now be implemented easily. Go ahead and give it a shot! We hope you like it.

Feedback is always welcome in the form of comments to this post or — even better — bug reports or enhancement requests on GitHub.

If you are looking for help with React or GraphQL development on your next project we’d love to hear from you at Functional Foundry.

--

--