GraphQL and Microservices

My company has been using GraphQL in production for about a year. Maintaining the schemas in our "Platform API" and also in our microservices became arduous. Developers kept asking us why they needed to do double work and what the benefit was. Especially since we required in-depth code reviews to change/update the production GraphQL schema

Apollo GraphQL released schema stitching which has solved most of the problems we were having. Essentially individual microservices each maintain their own GraphQL endpoint, then our Node.js Platform API stitches them all together. The resulting API is a client developer's dream, and the backend developers get the level of autonomy about their code they're used to. I highly recommend trying schema stitching. We've been adopting it incrementally for a few months and it's been wonderful.

As an added benefit, while defining our sub-schemas we started decoupling certain microservices, instead relying on the stitched data extensions to fill in holes in objects. Feels like the missing piece in DDD


Great question! Sounds like you're asking how to set up your architecture for GraphQL and microservices, and why.

Background

I would recommend using GraphQL since it's best use case is to consolidate data sources in a clean way and expose all that data to you via one standardized API. On the flip side, one of the main problems with using microservices is that it's hard to wrangle all the different functions that you can possibly have. And as your application grows, it becomes a major problem with consolidating all these microservice functions.

The benefits of using these technologies are tremendous since now you essentially have a GraphQL API gateway that allows you to access your microservices from your client as if it were a single monolithic app, but you also get the many benefits of using microservices from a performance and efficiency standpoint.

Architecture

So the architecture I would recommend is to have a GraphQL proxy sitting in front of your microservices, and in your GraphQL query and mutation resolvers, call out to the function that you need to retrieve the necessary data.

It doesn't really matter all that much between having a GraphQL gateway in front of GraphQL microservices or a GraphQL gateway in front of REST endpoints, although I would actually argue that it would be simpler to expose your microservice functions as REST endpoints since each function should theoretically serve only one purpose. You won't need the extra overhead and complexities of GraphQL in this case since there shouldn't be too much relational logic going on behind the scenes.

If you're looking for microservice providers the best ones that I've seen are AWS Lambda, Webtask, Azure Functions, and Google Cloud Functions. And you can use Serverless as a way to manage and deploy these microservice functions.

For example:

import request from 'request';

// GraphQL resolver to get authors
const resolverMap = {
  Query: {
    author(obj, args, context, info) {
      // GET request to fetch authors from my microservice
      return request.get('https://example.com/my-authors-microservice');
    },
  },
};

GraphQL Service

This is something that we've been exploring at Scaphold as well in case you'd like to rely on a service to help you manage this workflow. We first provide a GraphQL backend service that helps you get started with GraphQL in a matter of minutes, and then allow you to append your own microservices (i.e. custom logic) to your GraphQL API as a composition of functions. It's essentially the most advanced webhook system that's gives you flexibility and control over how to call out to your microservices.

Feel free to also join the Serverless GraphQL Meetup in SF if you're in the area :)

Hope this helps!


You are asking about how to use GraphQL in a microservice architecture. One approach you are considering is that all microservices are GraphQL. The other approach is using GraphQL as the API gateway and REST for the backend data APIs.

In a recent evaluation which includes load tests of Node based data API microservices, I concluded that Express (REST) was more efficient than Apollo (GraphQL). It turns out that the general purpose parsing and executing of GraphQL queries can be relatively expensive when compared to JSON parsing with specific, hand coded API handlers. In light of that discovery, I would suggest keeping the data APIs RESTful.