#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();