使用无服务器时的 GraphQL "Schema must contain uniquely named types"

GraphQL "Schema must contain uniquely named types" when using Serverless

我正在尝试使用无服务器和 AWS Lambda 部署 NestJS GraphQL API 服务器。当 运行 本地应用程序时,我可以毫无问题地使用 GraphQL 游乐场,但是当 运行 无服务器离线时,我收到以下错误:

Error: Schema must contain uniquely named types but contains multiple types named "Constellation".

错误表明 ObjectTypes ConstellationAffix 不是唯一的。它们都是 ObjectTypes,表示字段的类型:

模式模式

// character.model.ts

import mongoose, { Document, Schema as MongooseSchema } from 'mongoose';

import { Field, ObjectType } from '@nestjs/graphql';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';

@ObjectType('Constellation')
class Constellation {
  @Field(() => String)
  effect: string;

  @Field(() => Number)
  oid: number;

  @Field(() => String)
  name: string;

  @Field(() => Number)
  pos: number;

  @Field(() => String)
  icon: string;
}

@ObjectType()
@Schema({ timestamps: true })
export class Character {
  @Field(() => String)
  _id: MongooseSchema.Types.ObjectId;

  @Field(() => Number)
  @Prop({ required: true, unique: true })
  oid: number;

  @Field(() => [Constellation])
  @Prop({ required: true })
  constellations: Constellation[];

  @Field(() => String)
  @Prop({ required: true })
  element: string;

  @Field(() => String)
  @Prop({ required: true })
  name: string;

  @Field(() => Number)
  @Prop({ required: true })
  rarity: number;

  @Field(() => String)
  @Prop({ required: true })
  icon: string;

  @Field(() => String)
  @Prop({ required: true })
  image: string;
}

export type CharacterDocument = Character & Document;
export const CharacterSchema = SchemaFactory.createForClass(Character);
export default mongoose.model<CharacterDocument>(Character.name, CharacterSchema);
// artifact-set.model.ts

import mongoose, { Document, Schema as MongooseSchema } from 'mongoose';

import { Field, ObjectType } from '@nestjs/graphql';
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';

@ObjectType('Affix')
export class Affix {
  @Field(() => Number)
  activation_number: number;

  @Field(() => String)
  effect: string;
}

@ObjectType()
@Schema({ timestamps: true })
export class ArtifactSet {
  @Field(() => String)
  _id: MongooseSchema.Types.ObjectId;

  @Field(() => Number)
  @Prop({ required: true, unique: true })
  oid: number;

  @Field(() => [Affix])
  @Prop({ required: true })
  affixes: Affix[];

  @Field(() => String)
  @Prop({ required: true })
  name: string;
}

export type ArtifactSetDocument = ArtifactSet & Document;
export const ArtifactSetSchema = SchemaFactory.createForClass(ArtifactSet);
export default mongoose.model<ArtifactSetDocument>(ArtifactSet.name, ArtifactSetSchema);

进口

由于我发现导入这些模型可能是问题的根源,因此我还提供了一个示例导入:

import { Affix, ArtifactSet } from '../artifact-set/artifact-set.model';

这是导入到另一个模型的 ../character/character.service 中的 service 文件中,而不是导入到其他地方。 Constellation ObjectType 未在其他任何地方显式导入,但却是第一个引发错误的类型。

serverless.yml

app: server
service: server-api
useDotenv: true

package:
  patterns:
    - '!dist/**'
    - '!src/seeds/**'

plugins:
  - serverless-plugin-typescript
  - serverless-offline

# custom:
#   serverless-offline:
#     allowCache: true

provider:
  name: aws
  profile: serverless-admin
  runtime: nodejs12.x
  lambdaHashingVersion: 20201221

functions:
  main:
    handler: src/lambda.handler
    events:
      - http:
          path: graphql
          method: POST
          cors: true
          integration: LAMBDA
      - http:
          path: graphql
          method: GET
          cors: true
          integration: LAMBDA
      - http:
          path: playground
          method: ANY
          cors: true
          integration: LAMBDA

尝试次数

根据对面临类似问题的用户的研究,我尝试了以下方法:

  1. 仔细检查导入内容是否有拼写错误,大小写相同
  2. 更改 class 名称,在装饰器中指定名称(例如 ObjectType('Constellation')
  3. 更改导入以使用绝对路径(src/../..)
  4. 使用types/interfaces代替ObjectType
  5. 从模式中删除 mongoose 默认导出

我不能确定这是你的问题,但我在使用 nest 和 serverless-offline 时遇到了同样的错误。

为我解决的问题是将 --allowCache 添加到无服务器离线命令中。 See Docs

npx serverless offline --allowCache

否则,我的 server 变量不会被缓存,但不知何故 OrphanedReferenceRegistry 会在函数调用之间被缓存。每次我点击 URL 我的服务器都会再次启动,我的 ObjectType 会添加到现有注册表中,这会在创建模式时触发错误,因为有 2+ 个相同的 ObjectType。

这是我的笔记,以供参考,以防对遇到类似问题的人有所帮助 https://github.com/pope-12/nest-graphql-serverless-error