Federated microservices

Microservices oriented architecture are a still growing trend and events-based systems seems to be a good way to handle the latest business challenges.

REST is a common standard to expose resources to external world such web and mobile applications. Even thus, Rest Web Api based services suffer from some long-term problems specially in large teams working on not-short and long lifecycle projects. In the .NET world, as example, MVC is still very common choice to build the Api layer of our services, but the maintenance of their signatures hide some long term issues.

  • New features needs different Api with much or fewer data, in different formats or with different parameters
  • Api versioning needs to be handled at some point
  • The coexistence of mobile and web applications usually require similar resources in slightly different ways
  • Often many calls get more data than needed

There could be more of these, anyway the problem to maintain well documented REST Web Api layers can be time-consuming and increases the risk of a misunderstanding arising.

And here’s where GraphQL come to play.

GraphQL

GraphQL is a query language for Api capable to get many resources in a single request.

Basically, each service has a unique endpoint to feed the client applications through a unified graph.

The learning curve can be steep, but it’s just fabulous!

Usually a service implements a schema, a schema hold query and mutation operations on the service domain objects. But why is so useful in microservices oriented architectures ?

Apollo platform

Apollo graph platform is an open source graphQL server client implementation. We are so interested to the federated schema feature.

In a federated architecture, your graph’s API is implemented across multiple services instead of a monolithic server. Each service has its own GraphQL schema, and those schemas are merged by a gateway that intelligently executes operations across services.

Federated schema implementation

Our architecture is polyglot and a Node proxy act as a backend for frontend layer.

Example architecture diagram
Just a fragment of our demo architecture

GraphQL born as javascript framework, .NET has his implementation. Several others are available in other languages.

In our example we have persons, relationships, accounts and deposits domain entities. These are managed by different services, as DDD good practices says.

Domain example

Our goal is to supply a single relational graph for the whole business. Moreover, entity has relationships to each other as show above.

Let’s start with NodeJs services, the Person service. In a GraphQL endpoint, there are two main things to do.

Define a schema,

Schema definitions in GraphQL language

Note that Relationship entity is mentioned because Person needs to be aware about it.

And resolvers,

Resolvers of the person service

In this case, we have only query in our resolvers, just to start easy.
Finally, start the server,

These steps are pretty similar for all the Node Js services. For each of these, a GraphQL playground is available on the relative url:

GraphQL interactive playground of person endpoint

Let’s talk about the GraphQL-dotnet implementation who implements the deposit service.

Actually, federated schema feature is present in GraphQL.Utilities.Federation assembly, but seems to be not very complete. I found a pull-request and a discussion about that feature. mac2000 did a good job providing the necessary abstractions.

Federation schema declared as a code first,

Deposit graph type

I know, in .NET we need much more code than javascript …but that’s not always a bad thing…

Federated schema
GraphQL setup in Startup class

As we mentioned earlier, we want to expose all these services as a whole graph, then we need the gateway service to merge all the federated schema.

Gateway code
Federated microservices example architecture with GraphQL

At this stage:
We can access to the entire unified graph from the gateway service exposed, the underlying services interactions are totally hiding under the hood.
Consumers can ask relational resources, even partially, supplied across services without realizing it!

Gateway playground

The complete codebase of this example is available here.

Software Craftsman @ Blazar Group SA