Nestjs / GraphQL-操场返回空错误查询。我的解决者?

时间:2019-03-08 18:24:45

标签: graphql nestjs

我的浏览器中的Playground很好地显示了Nestjs创建的架构,但是查询返回了null。我的代码有问题吗?

"errors": [
    {
      "message": "Cannot return null for non-nullable field Query.getUsers.",
      "locations": [
        {
          "line": 2,
          "column": 3
    }

这意味着找不到数据。

schema.graphql:

type UsersGQL {
    User_id: ID!
    first_name: String!
    last_name: String!
    main_skill_title: String!
    user_name: String!
    ....
}

type Query {
    getUser(user_id: ID!): UsersGQL!
    getUsers: [UsersGQL!]!
}

在带有GraphQL的Nestjs中编译为graphql.schema.ts

export class UsersGQL {
    user_id: string;
    first_name: string;
    last_name: string;
    main_skill_title: string;
    user_name: string;
    ...
}

export abstract class IQuery {
    abstract getUser(user_id: string): UsersGQL | Promise<UsersGQL>;

    abstract getUsers(): UsersGQL[] | Promise<UsersGQL[]>;

    abstract temp__(): boolean | Promise<boolean>;
}

users.resolvers.ts

import { Query, Resolver } from '@nestjs/graphql';
import { UsersService } from './users.service';

import { UsersGQL } from '../graphql.schema';
// import { UsersDTO } from './users.dto';


@Resolver('UsersGQL')
export class UsersResolvers {
  constructor(
    private readonly userService: UsersService
  ) {}

  @Query()
  async getUsers() {
    return await this.userService.findAll();
  }
}

该服务适用于我的Nestjs REST API。数据库是Postgres。

users.service.ts

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, getManager, getRepository } from 'typeorm';
import { Members } from './members.entity';

@Injectable()
export class UsersService {

  private entityManager = getManager();

  constructor(
    @InjectRepository(Users)
    private readonly usersRepository: Repository<Users>
  ) {}

  async findAll(): Promise<Users[]> {
    return await this.usersRepository.find();
  }
}

游乐场查询:

{
  getUsers {
    first_name
    last_name
  }
}

在Playground中返回的错误:

{
  "errors": [
    {
      "message": "Cannot return null for non-nullable field Query.getUsers.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "getUsers"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
             ...
  ],
  "data": null
}

编辑-添加了users.module.ts,app.module.ts和ormconfig.json。整个模块是延迟加载的。 REST和GraphQL在模块中并排放置。我还分离了REST和GQL组件。

users.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

// REST
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { Users } from './users.entity';

// GraphQL
import { UsersResolvers } from './users.resolvers';

@Module({
  imports: [
    TypeOrmModule.forFeature([
      Users
      ]),
  ],
  providers: [
    UsersService,
    UsersResolvers
  ],
  controllers: [UsersController],
})

export class UsersModule {}

app.module.ts

import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';

import { TypeOrmModule } from '@nestjs/typeorm';
import { GraphQLModule } from '@nestjs/graphql';
import { join } from 'path';

import { LoggerMiddleware } from './logger.middleware';

import { UsersModule } from './users/users.module';

import { UsersController } from './users/users.controller';



@Module({
  imports: [
    TypeOrmModule.forRoot(),
    GraphQLModule.forRoot({
      typePaths: ['./**/*.graphql'],
      definitions: {
        path: join(process.cwd(), 'src/graphql.schema.ts'),
        outputAs: 'class',
      },
      debug: true,
    }),
    UsersModule
  ],
  controllers: [
  ],
  exports: [
  ],
  providers: [
  ]
})

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .with('AppModule')
      .forRoutes(
        UsersController
    )};
}

ormconfig.json

...
"entities": [
    "src/**/**.entity{.ts,.js}",
    // "src/graphql.schema.ts"  This doesn't work.  Must use REST entity.
  ],
...

3 个答案:

答案 0 :(得分:0)

您可能是从@Query而非'@nestjs/common'导入了'@nestjs/graphql'

确保具有:

import { Query } from '@nestjs/graphql';

答案 1 :(得分:0)

TL; DR

您的架构已正确公开(并且可以通过操场使用)这一事实并不一定意味着所有相应的模块和解析器都已集成到正在运行的Nest应用程序中。


我最近遇到了同样的错误,原因很简单:我忘记了将包含解析器的模块导入到根模块中-通常为AppModule

因此:您确定已导入所有UserModule模块依赖项(并且最重要的是UserResolver)并且UsersModule本身已导入到AppModule吗?

这里的技巧是服务器公开的GraphQL模式是直接从源文件生成的。根据您的Nest GraphQL配置,它将所有.graphql.gql个文件编译在一起(schema first approach);或带有Nest v6的type-graphql模块,将读取您的所有源文件以寻找其修饰符并生成schema.gqlcode first approach)。因此,即使没有实际的模块来解决您的请求,您也可以公开正确的架构。

IMO,这是框架中的错误行为,因为它在没有提供任何解释的情况下默默地无法解析您的架构。您收到的简单错误消息(Cannot return null for non-nullable field Query.getUsers.)颇具误导性,因为它隐藏了真正的失败,这是残缺的依赖关系

有关更多信息,这是相关的GitHub问题:https://github.com/nestjs/graphql/issues/198

答案 2 :(得分:0)

使用这种TypeORM架构的“解决方案”是使用REST实体,而不是架构。我不喜欢这种解决方案。我想通过GraphQL转换删除所有REST组件。使用TypeORM的优点是数据库连接。为此需要一些东西,而TypeORM可以与Nestjs一起使用。

我看到的问题是需要GraphQL模式和TypeORM实体。这不是DRY。

users.resolvers.ts

import { Query, Resolver } from '@nestjs/graphql';
import { UsersService } from './users.service';
import { Users } from './users.entity';

// import { UsersGQL } from '../graphql.schema';
// import { UsersDTO } from './users.dto';


// @Resolver('UsersGQL')
@Resolver('Users')
export class UsersResolvers {
  constructor(
    private readonly userService: UsersService
  ) {}

  @Query()
  async getUsers() {
    return await this.userService.findAll();
  }
}