I'm trying to deploy a NestJS GraphQL API server with Serverless and AWS Lambda. When running the app locally I am able to use the GraphQL playground without any issues, but when running Serverless offline I get the following error:
Error: Schema must contain uniquely named types but contains multiple types named "Constellation".
The error states that ObjectTypes Constellation and Affix are not unique. These are both ObjectTypes that represent the type for a field:
MODEL SCHEMAS
// 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);
IMPORTS
Since I've seen that importing these models could be a source of the problem, I've also included an example import:
import { Affix, ArtifactSet } from '../artifact-set/artifact-set.model';
This is imported into a service file in ../character/character.service for another model, and is not imported elsewhere. The Constellation ObjectType is not explicitly imported anywhere else, yet is the first type to raise an error.
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
ATTEMPTS
I've tried the following based on research of users facing similar problems:
- Double check that imports have no typos, are all same case
- Change class name, specify name within decorator (ex.
ObjectType('Constellation') - Change imports to use absolute path (
src/../..) - Use types/interfaces instead of
ObjectType - Remove the mongoose default export from schemas