我的浏览器中的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。 db是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.
],
...
你可能从@Query
而不是'@nestjs/common'
进口了'@nestjs/graphql'
。
确保有:
import { Query } from '@nestjs/graphql';
TL; DR
您的架构被正确公开(并且可以通过游乐场获得)这一事实并不一定意味着所有相应的模块和解析器都集成到您正在运行的Nest应用程序中。
我最近遇到了同样的错误,原因很简单:我忘了将包含解析器的模块导入到根模块 - 通常是AppModule
。
那么:你确定你所有的UserModule
模块依赖项(以及所有UserResolver
)都已导入并且UsersModule
本身导入了你的AppModule
吗?
这里的技巧是服务器公开的GraphQL架构直接从源文件生成。根据您的Nest GraphQL配置,它将汇集所有.graphql
,.gql
文件(schema first approach);或者使用Nest v6的type-graphql模块将读取所有源文件以查找其装饰器并生成schema.gql
(code first approach)。因此,即使没有实际模块解析您的请求,您也可以公开正确的架构。
IMO,这是一个来自框架的错误行为,因为它在没有提供任何解释的情况下默默地无法解析您的架构。你得到的简单错误信息(Cannot return null for non-nullable field Query.getUsers.
)是非常误导的,因为它隐藏了真正的失败,这是一个破坏的依赖。
有关更多信息,请参阅相关的GitHub问题:https://github.com/nestjs/graphql/issues/198
此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();
}
}