개발자/오류

[GraphQL] Cannot return null for non-nullable field Query. 배열편

YoungDogg 2022. 2. 15. 09:15

 

fetchBoard : [Board!]! 타입이다.

[안쪽느낌표!] [바깥쪽]!
배열의 값이 null이 될 수 없다는 뜻 배열이 없어선 안된다는 뜻

(참고: javascript - GraphQL: Non-nullable array/list - Stack Overflow)


문제는 둘 중 하나다.

  1. 받아오는 배열이 없어서
  2. 받아온 배열에 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'}

쓰면 된다