Nestjs / GraphQL - Playground возвращает нулевую ошибку для запроса. Мои решатели? - PullRequest
0 голосов
/ 08 марта 2019

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!]!
}

Компилируется в Nestjs с GraphQL в 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();
  }
}

Служба отлично работает для моих REST API Nestjs.БД - 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
  }
}

Ошибка, возвращаемая на игровой площадке:

{
  "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 ]

1 голос
/ 04 апреля 2019

TL; DR

Тот факт, что ваша схема правильно выставлена ​​(и доступна через игровую площадку), не обязательно означает, что все соответствующие модули и резольверы интегрированы в ваш бегПриложение Nest.


Недавно я столкнулся с той же ошибкой, и причина была довольно проста: я забыл импортировать модуль, включая распознаватель, в корневой модуль - обычно AppModule.

Итак: вы уверены, что у вас есть все ваши UserModule зависимости модуля (и прежде всего UserResolver), импортированные и сам UsersModule, импортированный в ваш AppModule?

Хитрость в том, чтоСхема GraphQL, предоставляемая вашим сервером, генерируется напрямую из ваших исходных файлов.В соответствии с вашей конфигурацией Nest GraphQL он скомпилирует все файлы .graphql, .gql вместе ( первый подход к схеме );или модуль type-graphql с Nest v6 прочитает все ваши исходные файлы в поисках декораторов и сгенерирует код schema.gql (, первый подход ).Как следствие, вы можете выставить правильную схему, даже не имея реального модуля, обрабатывающего ваш запрос.

IMO, это некорректное поведение фреймворка, так как он молча не может разрешить вашу схему без объяснения причин.Получаемое вами простое сообщение об ошибке (Cannot return null for non-nullable field Query.getUsers.) вводит в заблуждение, поскольку оно скрывает реальный сбой, который является нарушенной зависимостью .

Для получения дополнительной информации, вот связанная проблема GitHub:https://github.com/nestjs/graphql/issues/198

1 голос
/ 08 марта 2019

Вы, вероятно, импортировали @Query из '@nestjs/common' вместо '@nestjs/graphql'.

Убедитесь, что у вас есть:

import { Query } from '@nestjs/graphql';
0 голосов
/ 05 апреля 2019

«Решением» этой архитектуры TypeORM является использование сущности TypeORM.

users.resolvers.ts

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

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

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