Fred Mériot
Fred Mériot

Reputation: 4357

NestJS + GraphQL Federation and schema first GraphQLDefinitionsFactory

I'am trying to use the GraphQL federation with the schema first approach. Before I switch to federation, I was using ts-node and a little script to generate my typings like this :

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';


const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.schema.ts'),
  outputAs: 'class',
});

This was working well until I switch to the federation approach and modifying my schema adding the @Key() directive in my sites.graphql file (schema first!) :

type Site @key(fields: "siteId")  {
  siteId: ID!
  contractId: Int
  dateStart: String
  siteName: String
}

type Query {
    GetSite(id: ID!): Site
}

Now, when I generate my classes, I have the following error :

> ts-node src/tools/generate-typings.ts
(node:84388) UnhandledPromiseRejectionWarning: Error: Unknown directive "@key".

The @key directive does not seem to be recognized. Do I miss something?

Thank you for your help

Upvotes: 0

Views: 2789

Answers (3)

Raskanskyz
Raskanskyz

Reputation: 65

For federated subgraphs you should used GraphQLFederationDefinitionsFactory instead:

import { join } from 'path';
import { GraphQLFederationDefinitionsFactory } from '@nestjs/graphql';

const definitionsFactory = new GraphQLFederationDefinitionsFactory();

definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.ts'),
  defaultScalarType: 'unknown',
  customScalarTypeMapping: {
    DateTime: 'Date',
  },
  watch: true,
});

Upvotes: 2

dhaval9989
dhaval9989

Reputation: 27

I have created the script to generate the federation schema

import { writeFileSync, readFileSync } from 'fs';
import { buildSubgraphSchema } from '@apollo/subgraph';
import { printSchema, DocumentNode } from 'graphql';
import gql from 'graphql-tag';

async function generateSchema() {
  // auto generate  schema file
  const subGraphschema = readFileSync('./src/schema/schema.graphql', {
    encoding: 'utf8',
    flag: 'r',
  });
  const schema: DocumentNode = gql(subGraphschema);

  const generatedSchema = buildSubgraphSchema({
    typeDefs: schema,
  });
  writeFileSync(
    './public/schema.graphql',
    printSchema(generatedSchema),
    'utf8',
  );
  console.log(`Generated GraphQL schema:\n\n${printSchema(generatedSchema)}`);
}
generateSchema();

Upvotes: 0

Fred Mériot
Fred Mériot

Reputation: 4357

Ok, digging in the source code of graphql-definitions.factory.ts I found an undocumented option federation.

Changing my script to :

import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
import { join } from 'path';


const definitionsFactory = new GraphQLDefinitionsFactory();
definitionsFactory.generate({
  typePaths: ['./src/**/*.graphql'],
  path: join(process.cwd(), 'src/graphql.schema.ts'),
  outputAs: 'class',
  federation: true
});

And it works now.

Ps: to run the project, don't forget to eventually disable the installSubscriptionHandlers in the GraphQLModule options.

Upvotes: 2

Related Questions