'`__typename` returned by the server isn't match to graphql schema

When I build schema using type-graphql and make a server with apollo-server-lambda and deploy it to netlify functions, something wrong happened.

schema generated by type-graphql

# -----------------------------------------------
# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!
# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!
# -----------------------------------------------

type Project {
  name: String!
  summary: String!
  titleAndSummary: String!
}

type Query {
  projects: [Project!]!
}

Problem

I think when I query to API

{
  __schema {
    types {
      name
    }
  }
}

API must respond like

{
    "data": {
        "__schema": {
            "types": [
                {
                    "name": "Query"
                },
                {
                    "name": "Project"
                },
                // ...
            ]
        }
    }
}

But I got

{
    "data": {
        "__schema": {
            "types": [
                {
                    "name": "Query"
                },
                {
                    "name": "a"
                },
                // ...
            ]
        }
    }
}

I'm going to use graphql with Elm-Graphql what auto-generate modules using their __typename property. That's why I must fix the above problem.

I try hard to resolve it but even can't find where's the problem. It seems like in type-graphql or apollo-server or even netlify functions (I tried both netlify dev server and real server with actual deployment)

Codes

graphql.ts

import 'reflect-metadata';
import { ApolloServer } from 'apollo-server-lambda';
import { buildSchemaSync } from 'type-graphql';
import { QueryResolver, ProjectResolver } from './resolver';

const schema = buildSchemaSync({
  resolvers: [QueryResolver, ProjectResolver],
});

const server = new ApolloServer({
  schema,
  debug: false,
});

export const handler = server.createHandler();

types.ts

import { ObjectType, Field } from 'type-graphql';

@ObjectType()
export class Query {
  @Field((type) => [Project!]!)
  projects!: Project[];
}

@ObjectType()
export class Project {
  @Field((type) => String!)
  name!: string;

  @Field((type) => String!)
  summary!: string;
}

resolver.ts

import { Resolver, Query, FieldResolver, Root } from 'type-graphql';
import { Project } from './types';
import { projectList } from '../../db/fakeDB';

@Resolver()
export class QueryResolver {
  @Query((returns) => [Project])
  projects() {
    return projectList;
  }
}

@Resolver((of) => Project)
export class ProjectResolver {
  @FieldResolver((returns) => String!)
  titleAndSummary(@Root() project: Project) {
    return project.name + ' ++ ' + project.summary;
  }
}

Trial

add __typename to Objec Type directly like below

 @Resolver((of) => Project)
export class ProjectResolver {
  @FieldResolver((returns) => String!)
  titleAndSummary(@Root() project: Project) {
    return project.name + ' ++ ' + project.summary;
  }

  @FieldResolver((returns) => String!)
  __typename() {
    return 'Project';
  }
}

But It throws an error on the request

◈ Error during invocation:  {
  errorMessage: 'Name "__typename" must not begin with "__", which is reserved by GraphQL introspection.',
  errorType: 'Error',
...

How can I solve it?

Because I'm not good at English, I worry about If there's a wrong thing. please let me know and correct. Thanks.



Solution 1:[1]

We see this with SST and TypeGraphQL when run in production. The "__typename" attribute of ObjectType() and InputType() classes are being transformed into two letter codes. See photo.

Micha?, can you elaborate on the bundle minification in TypeGraphQL and how it can be configured to maintain the class names of the source code ObjectType() and InputType() declarations?

"@serverless-stack/cli": "0.54.4",
"@serverless-stack/resources": "0.54.4",    
"apollo-server-lambda": "^2.21.1",
"type-graphql": "^1.1.1",

const server = new ApolloServer({
  schema: buildSchemaSync({
    resolvers: [getWebPaths],
    scalarsMap: [],
    validate: false,
  }),

  playground: true, //IS_LOCAL,
  introspection: true, // IS_LOCAL,

  context: async ({
    context,
    event,
  }: {
    event: APIGatewayEvent
    context: Context
  }): Promise<LambdaRoot> => {
    context.callbackWaitsForEmptyEventLoop = false

    return {
      event,
      context,
    }
  },
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user18263864