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 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 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.
In our example we have persons, relationships, accounts and deposits domain entities. These are managed by different services, as DDD good practices says.
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,
Note that Relationship entity is mentioned because Person needs to be aware about it.
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:
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,
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.
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!
The complete codebase of this example is available here.