我正在使用带有 NestJS 的代码优先方法来处理 GraphQL,并使用 Nx 设置 monorepo。
schema.gql
仅在我运行服务器时产生,而在 CI 期间我无法做到这一点。将整个存储库复制到 docker 映像并启动服务器对我来说是不切实际的。当您构建嵌套应用程序时,不会生成 schema.gql
。
我还查看了 NestJS 网站上的手动生成 SDL 文档,但不太确定如何集成该脚本。
只是想知道是否有人在不启动服务器的情况下成功生成了模式?
以下内容对我来说效果很好。我在这里的文档中发现了这一点:
https://docs.nestjs.com/graphql/quick-start#accessing- generated-schema
我添加了一个检查来查看 ENV 是否是生产环境,因为我想要生成文件的位置在开发模式下已经存在。
import { NestFactory } from '@nestjs/core';
import { GraphQLSchemaHost } from '@nestjs/graphql';
import { writeFileSync } from 'fs';
import { printSchema } from 'graphql';
import { join } from 'path';
import { ServerModule } from './server.module';
async function bootstrap() {
const app = await NestFactory.create(ServerModule);
await app.listen(process.env.PORT || 3001);
if (process.env.NODE_ENV === 'production') {
const { schema } = app.get(GraphQLSchemaHost);
writeFileSync(join(process.cwd(), `/src/schema.gql`), printSchema(schema));
}
}
bootstrap();
设法弄清楚如何集成手动生成SDL。
只需在启动 Nest 服务器之前执行生成 SDL 函数即可。
下面包含完整示例。
const resolvers = [MyResolver]
/**
* Generate GraphQL schema manually. NestJS does not generate the GraphQL schema
* automatically during the build process and it doesn't generate the GraphQL
* schema when starting the built app. This schema needs to be generated or
* the GraphQL api would have nothing to use.
*
* @param {MyServices} serviceName - Name of the gavel service to generate a unique
* schema.
* @param {Function[]} resolvers - List of GraphQL resolvers being used in that app.
* @returns {Promise<void>} Nothing gets returned. It will just write the schema and
* throw an error if it fails.
*/
export async function generateGraphQLSchema(
serviceName: MyServices,
resolvers: Function[],
): Promise<void> {
const app = await NestFactory.create(GraphQLSchemaBuilderModule)
await app.init()
const gqlSchemaFactory = app.get(GraphQLSchemaFactory)
const schema = await gqlSchemaFactory.create(resolvers)
writeFileSync(join(process.cwd(), `/${serviceName}-schema.gql`), printSchema(schema))
}
/**
* Setup nest application.
*
* @param {string} port - Port the application should listen to.
* @param {unknown} appModule - Main app module from a nest application.
* @param {MyServices} serviceName - Name of the gavel service to generate a unique
* schema.
* @returns {Promise<void>}
*/
async function bootstrap(port: string, appModule: any, serviceName: MyServices): Promise<void> {
const app = await NestFactory.create(appModule)
// Endpoint prefix
const globalPrefix = `${config.get(`env`)}/v1/${serviceName}`
app.setGlobalPrefix(globalPrefix)
// Start Server
await app.listen(port, () => {
Logger.log(`Listening at http://localhost:${port}/${globalPrefix}/graphql`)
})
}
/**
* Helper to crate standard Nest JS Server.
*
* @param {MyServices} serviceName - Name of service.
* @param {unknown} appModule - Main app module from a nest application.
*/
export function initializeServer(serviceName: GavelService, appModule: any): void {
const environment = config.get(`env`)
const port = config.get(`port`)
initializeElasticApm(`service-${serviceName}`, {
framework: `nest`,
environment,
version: `${packageJson.version}`,
})
bootstrap(port, appModule, serviceName).catch((error) => {
const logger = getElasticSearchLogger(serviceName)
logger.error(
{ error, environment: config.get(`env`), applicationName: serviceName },
error.message,
)
})
}
generateGraphQLSchema(MyServices.SERVICE_A, resolvers)
.then(() => initializeServer(MyServices.SERVICE_A, AppModule))
.catch((e) => console.error(e))
更简单地实现手动生成 SDL
如果您使用 graphql cli 插件,请从
nest start --entryFile generate-schema
开始
src/generate-schema.ts
import { NestFactory } from '@nestjs/core';
import { GraphQLSchemaBuilderModule, GraphQLSchemaFactory } from '@nestjs/graphql';
import { writeFileSync } from 'fs';
import { printSchema } from 'graphql';
import { join } from 'path';
const resolvers = [
// Your resolvers here
];
const scalars = [
// Your scalars here
];
const main = async () => {
const app = await NestFactory.create(GraphQLSchemaBuilderModule);
await app.init();
const gqlSchemaFactory = app.get(GraphQLSchemaFactory);
const schema = await gqlSchemaFactory.create(resolvers, scalars);
writeFileSync(join(process.cwd(), '/schema.graphql'), printSchema(schema));
};
main();