As your Graphql backend grows there may come a time when you want to split the service into smaller components or microservices. This can help keep your domains isolated and speed up deployments. The really cool feature of the graphql system is federation, which will allow you to deploy isloated graphql backends and integrate them for your front-end.
Let's look at an example:
Our Domains
Let's continue with our example form last week of the system for a university. Let's say we want to integrate a finance system to track the accounts payable for our students.
Here is our model for the account balance. We link the balance to the student via student ID and track a very simple amount of data.
type accountBalance{
outstandingBalance: Int
paymentDue: String
StudentId: ID
}
Now, in order to implement the backend, we have 2 choices, we can integrate the payment system into our existing student backend or split them out into microservices. Since payments and class registrations aren't necessarily correlated, let's keep the separate.
The design will require us to deploy 3 services:
- a registration service
- an accounts payable service
- a gateway service to provide a unified front-end
Let's start with the gateway and work backwards from there.
The API Gateway
Api gateways are a feature of Graphql which allow you to aggregate types across micro-services without muddying your domains. NestJS is a great platform for this. To start with let's add the student object to our balance type:
type accountBalance{
outstandingBalance: Int
paymentDue: String
StudentId: ID
Student: Student
}
Now we need to identify how to fetch a student on our Student type, back in our first Service:
type Student @key(fields:'id'){
//
}
now in our student resolver we need to define how to fetch a student when requested by id:
@ResolveReference()
async resolveReference(
reference: {
__typename: string;
id: string;
},
context: IGraphqlContext
) {
const { id } = reference;
const user = await context.loaders.studentBySelfLoader.load(id);
return this.studentMapper.persistenceToGql(user);
}
Now we've defined how to fetch a student when requested by any other service we just need to link the two services together via a gateway.
Now we need to define a federation service to aggregate our domains
import {
ApolloFederationDriver,
ApolloFederationDriverConfig,
} from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { UsersResolver } from './users.resolver';
@Module({
imports: [
GraphQLModule.forRoot<ApolloFederationDriverConfig>({
driver: ApolloFederationDriver,
typePaths: ['**/*.graphql'],
}),
],
providers: [StudentsResolver, AccountResolver],
})
export class AppModule {}
Top comments (0)