我正在使用一个同时使用TypeORM和TypeORM的服务器应用程序。
@Field({ nullable: true })
@Column({ nullable: true })
url?: string; 当我运行GraphQL查询时(使用阿波罗工作室),有时查询会返回具有空值的错误,而其他情况下,当添加新值时,突变会失败。
我测试了多个变体,但结果不一致的结果将以奇怪的方式被拒绝。我查看了它,发现了从删除node_modules到删除数据库的建议,所以我决定我应该只知道在每个装饰器中做什么空设置。
将{ nullable: true }放入@field()或@column()之间有什么区别,而不应该简单地让?在类型定义中工作呢?
我还将我的@InputType()和@Entity()类分隔成不同的文件,所以是否也需要在输入中对@field()使用相同的值?
完整的例子:
实体
import { Field, ID, ObjectType } from "type-graphql";
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity()
@ObjectType()
export class Click extends BaseEntity{
@Field(type => ID)
@PrimaryGeneratedColumn("uuid")
id: string;
@Field(type => ID)
@Column({ nullable: true })
clickId?: string;
@Field({ nullable: true })
@Column({ nullable: true })
url?: string;
}输入
import { MaxLength } from "class-validator";
import { Field, ID, InputType } from "type-graphql";
import { Click } from '../entity/Click';
@InputType()
export class ClickInput implements Partial<Click> {
//omitted the id field because it's generated on the server
@Field(type => ID)
clickId: string;
@Field({ nullable: true })
@MaxLength(256)
url: string; Resolver
import {
Arg, Mutation,
Query,
Resolver
} from "type-graphql";
import { Service } from "typedi";
import { Click } from "../entity/Click";
import { ClickInput } from "../input/ClickInput";
import { ClickService } from "../service/ClickService";
@Service()
@Resolver(of => Click)
export class ClickResolver {
constructor(
// constructor injection of a service
private readonly clickService: ClickService,
) {}
@Query( returns => [Click])
async clicks() {
return this.clickService.list()
}
@Query( returns => Click, { nullable: true })
async click(@Arg("clickId") clickId: string) {
return this.clickService.findById(clickId)
}
@Mutation( _type => Click )
async createClick(@Arg("data") data: ClickInput): Promise<Click> {
return this.clickService.create(data)
}
}服务
import { Service } from "typedi";
import { DeleteResult } from "typeorm";
import { InjectRepository } from "typeorm-typedi-extensions";
import { Click } from "../entity/Click";
import { ClickRepository } from "../repo/ClickRepo";
@Service()
export class ClickService {
constructor(
@InjectRepository(Click)
private readonly clickRepository: ClickRepository
) {}
async findById(clickId: string, relations: string[] = []) {
return this.clickRepository.findOne({
where: {
clickId,
},
relations: relations,
});
}
async create(params: Partial<Click>): Promise<Click> {
const u = this.clickRepository.create(params);
return this.update(u);
}
async update(Click: Click): Promise<Click> {
return this.clickRepository.save(Click);
}
async delete(Click: Click): Promise<DeleteResult> {
return this.clickRepository.delete(Click)
}
async list() {
return this.clickRepository.find()
}
}发布于 2021-10-17 00:58:13
如果您想要一个值为null,则应该将其放在这两个值上。
{ nullable: true } in typeorm (@Entity)意味着允许数据库存储null值。否则,将不允许在数据库中的该列中保存空值。
{ nullable: true} in type-graphql (@Field)意味着TypeGraphQL生成的模式将允许该字段为null。否则,在查询时,可能会出现Cannot return null for non-nullable field EntityName.fieldName错误。
为了澄清,GraphQL模式可能如下所示:
type Click {
id: ID!
clickId: ID!
url: String
}注意url没有!,所以它不是必需的,但是clickId有,所以如果传递null值,就会遇到问题。
至于您的输入类型,是否允许传递用于null的clickId值?如果是这样的话,您还希望它是nullable: true in ClickInput。例如,如果您在创建时总是需要一个clickId,但后来将其设置为null,那么您可以忽略这一点,以要求clickId的输入为非空。
https://stackoverflow.com/questions/69597782
复制相似问题