迁移 Migrating to v11 from v10

导读

本章提供了从 @nestjs/graphql 版本 10 迁移到版本 11 的一组指南。作为此主要版本的一部分,我们更新了 Apollo 驱动程序以与 Apollo Server v4(而不是 v3)兼容。注意:Apollo Server v4 中有几个重大更改(尤其是插件和生态系统包),因此您必须相应地更新代码库。有关更多信息,请参阅 Apollo Server v4 迁移指南

Apollo 软件包

您不必安装 apollo-server-express 软件包,而是必须安装 @apollo/server

bash
$ npm uninstall apollo-server-express
$ npm install @apollo/server

如果您使用 Fastify 适配器,则必须安装 @as-integrations/fastify 软件包:

bash
$ npm uninstall apollo-server-fastify
$ npm install @apollo/server @as-integrations/fastify

Mercurius 软件包

Mercurius 网关不再是 mercurius 软件包的一部分。相反,您必须单独安装 @mercuriusjs/gateway 包:

bash
$ npm install @mercuriusjs/gateway

同样,要创建联合模式,您必须安装 @mercuriusjs/federation 包:

bash
$ npm install @mercuriusjs/federation

从 v9 迁移到 v10

本章提供了一组从 @nestjs/graphql 版本 9 迁移到版本 10 的指南。此主要版本发布的重点是提供更轻量、与平台无关的核心库。

引入驱动程序

在最新版本中,我们决定将 @nestjs/graphql 包拆分为几个单独的库,让您可以选择在项目中使用 Apollo(@nestjs/apollo)、Mercurius(@nestjs/mercurius)还是其他 GraphQL 库。

这意味着您现在必须明确指定您的应用程序将使用哪个驱动程序。

ts
Before
ts
import { Module } from '@nestjs/common'
import { GraphQLModule } from '@nestjs/graphql'

@Module({
  imports: [
    GraphQLModule.forRoot({
      autoSchemaFile: 'schema.gql',
    }),
  ],
})
export class AppModule {}

插件

Apollo Server 插件可让您执行自定义操作以响应某些事件。由于这是 Apollo 独有的功能,我们将其从 @nestjs/graphql 移至新创建的 @nestjs/apollo 包,因此您必须在应用程序中更新导入。

ts
// Before
import { Plugin } from '@nestjs/graphql'

// After
import { Plugin } from '@nestjs/apollo'

指令

schemaDirectives 功能已被 @graphql-tools/schema 包 v8 中的新 Schema 指令 API 取代。

ts
// Before
import { SchemaDirectiveVisitor } from '@graphql-tools/utils'
import { GraphQLField, GraphQLSchema, defaultFieldResolver } from 'graphql'

// After
import { MapperKind, getDirective, mapSchema } from '@graphql-tools/utils'

export class UpperCaseDirective extends SchemaDirectiveVisitor {
  visitFieldDefinition(field: GraphQLField<any, any>) {
    const { resolve = defaultFieldResolver } = field
    field.resolve = async function (...args) {
      const result = await resolve.apply(this, args)
      if (typeof result === 'string') {
        return result.toUpperCase()
      }
      return result
    }
  }
}

export function upperDirectiveTransformer(
  schema: GraphQLSchema,
  directiveName: string,
) {
  return mapSchema(schema, {
    [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
      const upperDirective = getDirective(
        schema,
        fieldConfig,
        directiveName,
      )?.[0]

      if (upperDirective) {
        const { resolve = defaultFieldResolver } = fieldConfig

        // Replace the original resolver with a function that *first* calls
        // the original resolver, then converts its result to upper case
        fieldConfig.resolve = async function (source, args, context, info) {
          const result = await resolve(source, args, context, info)
          if (typeof result === 'string') {
            return result.toUpperCase()
          }
          return result
        }
        return fieldConfig
      }
    },
  })
}

要将此指令实现应用于包含 @upper 指令的架构,请使用 transformSchema 函数:

ts
GraphQLModule.forRoot<ApolloDriverConfig>({
  ...
  transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
})

联合

GraphQLFederationModule 已被删除并替换为相应的驱动程序类:

ts
// Before
GraphQLFederationModule.forRoot({
  autoSchemaFile: true,
})

// After
GraphQLModule.forRoot<ApolloFederationDriverConfig>({
  driver: ApolloFederationDriver,
  autoSchemaFile: true,
})
提示

ApolloFederationDriver 类和 ApolloFederationDriverConfig 均从 @nestjs/apollo 包中导出。

同样,无需使用专用的 GraphQLGatewayModule,只需将适当的 driver 类传递给您的 GraphQLModule 设置即可:

ts
// Before
GraphQLGatewayModule.forRoot({
  gateway: {
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { name: 'users', url: 'http://localhost:3000/graphql' },
        { name: 'posts', url: 'http://localhost:3001/graphql' },
      ],
    }),
  },
})

// After
GraphQLModule.forRoot<ApolloGatewayDriverConfig>({
  driver: ApolloGatewayDriver,
  gateway: {
    supergraphSdl: new IntrospectAndCompose({
      subgraphs: [
        { name: 'users', url: 'http://localhost:3000/graphql' },
        { name: 'posts', url: 'http://localhost:3001/graphql' },
      ],
    }),
  },
})
提示

ApolloGatewayDriver 类和 ApolloGatewayDriverConfig 均从 @nestjs/apollo 包中导出。