【问题标题】:Nest.js GraphQL Schema generation during buildNest.js GraphQL Schema 在构建期间生成
【发布时间】:2021-07-21 16:50:27
【问题描述】:

我在 NestJS 中使用代码优先的 GraphQL 方法,并使用 Nx 设置了 monorepo。

schema.gql 仅在我运行服务器时生成,而在 CI 期间我无法执行此操作。将整个存储库复制到 docker 映像中并启动服务器对我来说是不切实际的。构建嵌套应用程序时不会生成schema.gql

我还查看了 NestJS 网站上的 Generating the SDL manually 文档,但不确定如何集成该脚本。

只是想知道是否有人在不启动服务器的情况下设法生成了架构?

【问题讨论】:

    标签: graphql nestjs


    【解决方案1】:

    设法弄清楚如何集成Generating the SDL manually

    只需在启动嵌套服务器之前执行生成 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))
    

    【讨论】:

      【解决方案2】:

      以下内容对我来说效果很好。我在这里的文档中发现了这一点:

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

      【讨论】:

        猜你喜欢
        • 2020-12-08
        • 2018-07-17
        • 2018-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多