Playground в моем браузере хорошо показывает созданную Nestjs схему, но запросы возвращаются null. Что-то не так с моим кодом?
"errors": [
{
"message": "Cannot return null for non-nullable field Query.getUsers.",
"locations": [
{
"line": 2,
"column": 3
}
Это означает, что данные не найдены.
схема.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>;
}
пользователи.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. БД это Постгрес.
пользователи.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.
пользователи.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.
],
...


Вероятно, вы импортировали @Query из '@nestjs/common' вместо '@nestjs/graphql'.
Убедитесь, что у вас есть:
import { Query } from '@nestjs/graphql';
Спасибо, Ким, но у меня есть на это право. Ранее я нашел эти другие сообщения SO об этом и был осторожен. Кроме того, я просто скопировал работу Камиля для его демо на Github :-)
Хорошо, жаль, это было бы легко исправить. ;-) Вы добавили console.info в свой сервис и убедились, что он вызывается и действительно возвращает непустой массив?
В вашем сервисе также есть опечатка, но это, вероятно, просто копия/вставка: userssRepository
Я поместил console.info в свою службу и преобразователь, но в окне терминала IDE ничего не произошло.
Я скопировал ваш код и попробовал, и у меня он работает. :-/ Можете ли вы удалить node_modules и переустановить свои зависимости и запустить npm update?
Новые node_modules и теперь изменения. Я только что добавил свой запрос Playground выше, возможно, проблема в этом. Первый раз с этим.
Нет, ваш запрос выглядит нормально. Ммм... Можете ли вы воспроизвести свою проблему на codeandbox.io?
Я попробую, но сначала мне нужно узнать о песочнице кода. Наверное, завтра, потому что это женский день, и моя русская жена хочет повеселиться :-) Я американец. Так что я не бросил тебя, если ты не будешь получать от меня вестей какое-то время.
Давайте продолжить обсуждение в чате.
TL;DR
Тот факт, что ваша схема правильно представлена (и доступна через игровую площадку), не обязательно означает, что все соответствующие модули и преобразователи интегрированы в ваше работающее приложение Nest.
Недавно я столкнулся с той же ошибкой, и причина была довольно проста: я забыл импортировать модуль, включая преобразователь, в корневой модуль — обычно AppModule.
Итак: вы уверены, что все ваши зависимости модуля UserModule (и, прежде всего, UserResolver) импортированы, а сам UsersModule импортирован в ваш AppModule?
Хитрость здесь в том, что схема GraphQL, предоставляемая вашим сервером, создается непосредственно из ваших исходных файлов. В соответствии с вашей конфигурацией Nest GraphQL он скомпилирует все файлы .graphql, .gql вместе (схема первый подход); или модуль type-graphql с Nest v6 прочитает все ваши исходные файлы в поисках декораторов и сгенерирует schema.gql (код первого подхода). Как следствие, вы можете предоставить правильную схему, даже не имея фактического модуля, разрешающего ваш запрос.
ИМО, это ошибочное поведение фреймворка, поскольку он молча не может разрешить вашу схему без каких-либо объяснений. Простое сообщение об ошибке, которое вы получаете (Cannot return null for non-nullable field Query.getUsers.), вводит в заблуждение, поскольку оно скрывает реальную ошибку, то есть сломанная зависимость.
Для получения дополнительной информации см. соответствующую проблему GitHub: https://github.com/nestjs/graphql/issues/198.
Спасибо, @MarsLevin! Да, member.module был импортирован в app.module как отложенная загрузка. Именно благодаря этому код REST работал хорошо до того, как я попытался настроить GraphQL. С тех пор я провел рефакторинг и отделил компоненты GraphQL, чтобы упростить устранение неполадок. Теперь я могу заставить Nestjs скомпилироваться. Я получаю сообщение об ошибке No repository for "MembersGQL" was found. Looks like this entity is not registered in current "default" connection? Я добавил переработанный код и модули, а также часть ormconfig.json в свой исходный пост. Есть идеи?
Я получил его, чтобы представить пользователей из моей базы данных Postgres в Playground, но мне не нравится, что он должен использовать объект REST. Я хочу удалить весь REST после того, как закончу преобразование в GraphQL.
«Решение» с этой архитектурой TypeORM заключается в использовании сущности TypeORM.
пользователи.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();
}
}
Если я сделаю запрос обнуляемым, удалю "!", тогда результаты запроса будут { "data": { "getMembers": null } } Это, по-видимому, означает, что данные не возвращаются через службу, которая в настоящее время работает нормально для моего REST API.