DEV Community

gaffleck
gaffleck

Posted on

1

Graphql Federation with NestJS and Apollo

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

}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

Now we need to identify how to fetch a student on our Student type, back in our first Service:

type Student @key(fields:'id'){
//
}
Enter fullscreen mode Exit fullscreen mode

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);
  }
Enter fullscreen mode Exit fullscreen mode

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 {}


Enter fullscreen mode Exit fullscreen mode

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay