使用无服务器时的 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 Constellation
和 Affix
不是唯一的。它们都是 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
尝试次数
根据对面临类似问题的用户的研究,我尝试了以下方法:
- 仔细检查导入内容是否有拼写错误,大小写相同
- 更改 class 名称,在装饰器中指定名称(例如
ObjectType('Constellation')
- 更改导入以使用绝对路径(
src/../..
)
- 使用types/interfaces代替
ObjectType
- 从模式中删除 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
我正在尝试使用无服务器和 AWS Lambda 部署 NestJS GraphQL API 服务器。当 运行 本地应用程序时,我可以毫无问题地使用 GraphQL 游乐场,但是当 运行 无服务器离线时,我收到以下错误:
Error: Schema must contain uniquely named types but contains multiple types named "Constellation".
错误表明 ObjectTypes Constellation
和 Affix
不是唯一的。它们都是 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
尝试次数
根据对面临类似问题的用户的研究,我尝试了以下方法:
- 仔细检查导入内容是否有拼写错误,大小写相同
- 更改 class 名称,在装饰器中指定名称(例如
ObjectType('Constellation')
- 更改导入以使用绝对路径(
src/../..
) - 使用types/interfaces代替
ObjectType
- 从模式中删除 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