파크로그
  • fakeDB [] 에서 sqlite 로 옮기던 와중, Many-To-One, One-To-Many 관계 설정을 하고 있었는데, 마지막 단계에서 아래와 같은 오류가 발생했다.

 

Cannot determine a GraphQL input type for the "...". Make sure your class is decorated with an appropriate decorator.

 

  • 아무리 눈을 씻고 찾아봐도 InputType 을 넣어주지 않은 클래스는 없었다. 혹시나 싶어 create input dto 를 뒤져보면서, OmitTypePickType 으로 로직을 바꾸어 사용해보니 위와 같은 에러가 사라졌다.

 

// 에러난 로직
@InputType()
export class CreateEpisodeInput extends OmitType(
  Episode,
  ['id', 'createdAt', 'updatedAt'],
  InputType,
) {
  @Field((type) => Number)
  @IsNumber()
  podcastId: number;
}
// 해결된 로직
@InputType()
export class CreateEpisodeInput extends PickType(
  Episode,
  ['title', 'category'],
  InputType,
) {
  @Field((type) => Number)
  @IsNumber()
  podcastId: number;
}

 

  • PickTypeOmitType은 내가 알기론 아래와 같았다.
    • PickType - Entity 중 원하는 Property 를 골라서 사용
    • OmitType - Entity 중 제외하기 원하는 Property 를 골라서 사용

 

@Entity()
@ObjectType()
export class Episode extends CommonEntity {
  @Column()
  @Field((type) => String)
  @IsString()
  title: string;

  @Column()
  @Field((type) => String)
  @IsString()
  category: string;

  @Column({ nullable: true })
  @Field((type) => Int, { nullable: true })
  @IsNumber()
  rating?: number;

  @ManyToOne(() => Podcast, (podcast) => podcast.episodes, {
    onDelete: 'CASCADE',
  })
  @Field((type) => Podcast)
  podcast: Podcast;
}

 

  • OmitType 은 CommonEntity 에 있는 id, createdAt, updatedAt 을 제외하기 원했었다.
    • 그렇다면 ManyToOne Field 인 podcast 도 제외해야 오류가 안나는 것일까?
    • 실험 결과 podcast 도 제외 하면 오류가 발생하지 않았다.
@InputType()
export class CreateEpisodeInput extends OmitType(
  Episode,
  ['id', 'createdAt', 'updatedAt', 'podcast'],
  InputType,
) {
  @Field((type) => Number)
  @IsNumber()
  podcastId: number;
}
  • Many-To-One, One-To-Many 와 같은 Relation 은 Input 에 포함될 필요 없이 typeORM 이 데이터베이스에 저장하는 것으로 이해하였다.
    • Field 를 그럼 꼭 넣어야하나?
      • GraphQL 에서 Input 말고도 Query 조회할 때 사용하니 GraphQL 에게 알려주는 Field 는 언제나 넣도록 하자
    @OneToMany(() => Episode, (episode) => episode.podcast)
    @Field((type) => [Episode])
    episodes: Episode[];

+) Relation Model 에 올바른 데이터 집어 넣기

  • podcastId 를 payload 에 포함시켜 (episodeData) 넣었는데 계속 null 을 반환했다.
  • 생각해보니 episode entity 에는 podcastId property 가 없는데 왜 계속 podcastId 를 넣으려고 했는지.. 로직을 변경해서 오류를 해결하였다.
    const { podcastId, ...payload } = episodeData;
    const { ok, podcast, error } = await this.getOne(podcastId);
    
    // 변경 전
    const newEpisode = this.episodeRepository.create(episodeData);
    await this.episodeRepository.save(newEpisode);
    
    // 변경 후
    const newEpisode = this.episodeRepository.create(payload);
    newEpisode.podcast = podcast;
    await this.episodeRepository.save(newEpisode);

 

  • 기존에 Podcast 에서는 fakeDB 를 썼기 때문에 episodes 가 없다면 defaultValue 로 빈 배열 ([]) 을 넣어주었는데, Relation 으로 체크해서 알아서 빈 배열을 넣어준다.
// 변경 전
@OneToMany(() => Episode, (episode) => episode.podcast)
@Field((type) => [Episode], { nullable: true, defaultValue: [] })
episodes?: Episode[];

// 변경 후
@OneToMany(() => Episode, (episode) => episode.podcast)
@Field((type) => [Episode])
episodes: Episode[];

 

아 널 주지 마요 응애

 

const podcasts = await this.podcastRepository.find();

// 변경 후
const podcasts = await this.podcastRepository.find({
		relations: ['episodes'],
}

Relation 을 넣은 테이블을 조회할 땐 relations 옵션을 꼭 넣도록 하자...^^

profile

파크로그

@파크park

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!