Объединение NestJS GraphQL и первая схема GraphQLDefinitionsFactory

#graphql #nestjs #federation

#graphql #nestjs #объединение

Вопрос:

Я пытаюсь использовать федерацию GraphQL с подходом schema first. Прежде чем я переключился на федерацию, я использовал ts-node и небольшой скрипт для генерации моих типов, подобных этому :

 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',
});
  

Это работало хорошо, пока я не переключился на подход федерации и не изменил свою схему, добавив директиву @Key() в свой sites.graphql файл (сначала схема!) :

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

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

Теперь, когда я создаю свои классы, у меня возникает следующая ошибка :

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

  

Директива @key, похоже, не распознается. Я что-то пропустил?

Спасибо за вашу помощь

Ответ №1:

Хорошо, покопавшись в исходном коде graphql-definitions.factory.ts , я нашел недокументированный вариант federation .

Меняю свой скрипт на :

 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
});
  

И теперь это работает.

Ps: чтобы запустить проект, не забудьте в конечном итоге отключить параметры installSubscriptionHandlers в GraphQLModule.

Ответ №2:

Для объединенных подграфов вы должны использовать GraphQLFederationDefinitionsFactory вместо:

 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,
});
  

Ответ №3:

Я создал скрипт для создания схемы федерации

 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:nn${printSchema(generatedSchema)}`);
}
generateSchema();