[GraphQL] Cannot return null for non-nullable field Query. 배열편
fetchBoard : [Board!]! 타입이다.
[안쪽느낌표!] | [바깥쪽]! |
배열의 값이 null이 될 수 없다는 뜻 | 배열이 없어선 안된다는 뜻 |
(참고: javascript - GraphQL: Non-nullable array/list - Stack Overflow)
문제는 둘 중 하나다.
- 받아오는 배열이 없어서
- 받아온 배열에 null값이 있어서
1. 받아오는 배열이 없어서
그럼 배열을 받지 않아도 되게 만들어보자.
// board.resolver.ts
import { Query, Resolver, Mutation, Args } from '@nestjs/graphql';
import { BoardService } from './board.service';
import { Board } from './entities/board.entity';
@Resolver()
export class BoardResolver {
constructor(private readonly boardService: BoardService) {}
@Query(() => [Board])
fetchBoards(): Board[] {
return this.boardService.findAll();
}
}
fetchBoards()에 관한 코드다. 이 코드에 약간 수정을 한다.
import { Query, Resolver, Mutation, Args } from '@nestjs/graphql';
import { BoardService } from './board.service';
import { Board } from './entities/board.entity';
@Resolver()
export class BoardResolver {
constructor(private readonly boardService: BoardService) {}
@Query(() => [Board], { nullable: true }) // <-------- 바뀐 부분
fetchBoards(): Board[] {
return this.boardService.findAll();
}
}
결과
오류가 뜨지 않게 잘 됐다.
2. 받아온 배열에 null값이 있어서
배열 안에 null 값이 있는 경우
writer에 null이 있으면 안된다고 한다.
배열 안 값들은 모두 느낌표가 붙어있는 걸로 보아 반드시 필요하다.
//board.service.ts
import { Injectable } from '@nestjs/common';
import { Board } from './entities/board.entity';
@Injectable()
export class BoardService {
findAll(): Board[] {
// 데이터 조회하는 로직
const arr = [
{
number: 1,
writer: null, // <--------- null 값을 집어넣은 곳
title: '제목입니다~',
contents: '내용이에요~~',
},
];
return arr;
}
}
writer에 null을 집어넣었었다. null을 집어넣으면 왜 오류가 났을까.
// board.entity.ts
import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
@ObjectType()
export class Board {
@PrimaryGeneratedColumn()
@Field(() => Int)
number: number;
@Column()
@Field(() => String)
writer: string;
@Column()
@Field(() => String)
title: string;
@Column()
@Field(() => String)
contents: string;
}
보드 엔티티는 이렇게 생겼다. 널이 되게 만들지 않으면 기본으로 널값을 받지 못하게 만든다.
널 값을 받아도 되게 만들자
import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
@ObjectType()
export class Board {
@PrimaryGeneratedColumn()
@Field(() => Int, { nullable: true })
number: number;
@Column()
@Field(() => String, { nullable: true })
writer: string;
@Column()
@Field(() => String, { nullable: true })
title: string;
@Column()
@Field(() => String, { nullable: true })
contents: string;
}
이제 다시 실행하면
오류가 뜨지 않는다. 또한 DOCS에서 QUERIS부분에 [board!], 느낌표를 없애지는 못했지만 타입 디테일에서 보면 객체의 모든 값들이 느낌표가 사라졌다.
안쪽 느낌표를 없애려면
// board.resolver.ts
import { Query, Resolver, Mutation, Args } from '@nestjs/graphql';
import { BoardService } from './board.service';
import { Board } from './entities/board.entity';
@Resolver()
export class BoardResolver {
constructor(private readonly boardService: BoardService) {}
@Query(() => [Board], { nullable: 'items' }) // <--- 바꾼 부분
fetchBoards(): Board[] {
return this.boardService.findAll();
}
}
nullable: 'items'로 바꾸면 된다. (참고 : GraphQL + TypeScript - Resolvers | NestJS - A progressive Node.js framework)
// board.service.ts
import { Injectable } from '@nestjs/common';
import { Board } from './entities/board.entity';
@Injectable()
export class BoardService {
findAll(): Board[] {
// 데이터 조회하는 로직
const arr = [ // 빈 배열만 반환하도록 했다.
// {
// number: 1,
// writer: null,
// title: '제목입니다~',
// contents: '내용이에요~~',
// },
];
return arr;
}
}
빈 배열만 반환하도록 했다.
빈 배열만 줘도 오류가 뜨지 않는다.
느낌표를 둘 다 없애려면
import { Query, Resolver, Mutation, Args } from '@nestjs/graphql';
import { BoardService } from './board.service';
import { Board } from './entities/board.entity';
@Resolver()
export class BoardResolver {
constructor(private readonly boardService: BoardService) {}
@Query(() => [Board], { nullable: 'itemsAndList' }) // 바뀐부분
fetchBoards(): Board[] {
return this.boardService.findAll();
}
}
itemsAndList를 넣어주면 된다.
// board.service.ts
import { Injectable } from '@nestjs/common';
import { Board } from './entities/board.entity';
@Injectable()
export class BoardService {
findAll(): Board[] {
// 데이터 조회하는 로직
// const arr = [
// // {
// // number: 1,
// // writer: null,
// // title: '제목입니다~',
// // contents: '내용이에요~~',
// // },
// ];
return;
}
}
아예 아무것도 반환 안하게 해보았다.
오류가 나지 않고 잘 뜬다. 심지어 타입 디테일에서 보드 객체의 각 값들은 느낌표가 붙어있어도 잘 된다.
결론
{nullable: true}
{nullable: 'items'}
{nullable: 'itemsAndList'}
쓰면 된다