본문 바로가기

Uber Eats

Uber Eats # 12 Create Restaurant

entity 파일 하나로 데이터베이스 테이블, graphql type, dto 한 번에 만들기

Mapped types

import { InputType, OmitType } from '@nestjs/graphql';
import { Restaurant } from '../entities/restaurant.entity';

@InputType()
export class CreateRestaurantDto extends OmitType(Restaurant, ["id"]){}

 

'Input Object type CreateRestaurantDto must define one or more fields.'

base class가 InputType 일 때 동작하는데 반해 restaurant.entity.ts는 아래와 같이 ObjectType이다.

import { Field, ObjectType } from "@nestjs/graphql";
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@ObjectType()
@Entity()
export class Restaurant {

    @PrimaryGeneratedColumn()
    @Field(type => Number)
    id: number;

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

    @Field(type => Boolean)
    @Column()
    isVegan: boolean;
  
    @Field(type => String)
    @Column()
    address: string;
  
    @Field(type => String)
    @Column()
    ownersName: string;
}

두 번째 인자에 InputType을 입력해준다. 

import { InputType, OmitType } from '@nestjs/graphql';
import { Restaurant } from '../entities/restaurant.entity';

@InputType()
export class CreateRestaurantDto extends OmitType(Restaurant, ["id"], InputType){}

또는 Restaurant entity에서 InputType decorator를 명시해주고 isAbstract:true를 해준다. 이는 InputType은 스키마에 포함되지 않고 어딘가에서 복사해서 쓰여짐을 의미한다. 이때 Dto에서 두 번째 인자는 지워준다. 

import { Field, InputType, ObjectType } from "@nestjs/graphql";
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@InputType({isAbstract:true})
@ObjectType()
@Entity()
export class Restaurant {

    @PrimaryGeneratedColumn()
    @Field(type => Number)
    id: number;

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

    @Field(type => Boolean)
    @Column()
    isVegan: boolean;
  
    @Field(type => String)
    @Column()
    address: string;
  
    @Field(type => String)
    @Column()
    ownersName: string;
}

GraphQL, Database, TypeScript을 적용한 최종 entity 파일은 아래와 같다.

import { Field, InputType, ObjectType } from '@nestjs/graphql';
import { IsBoolean, IsOptional, IsString, Length } from 'class-validator';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@InputType({ isAbstract: true })
@ObjectType()
@Entity()
export class Restaurant {
  @PrimaryGeneratedColumn()
  @Field(type => Number)
  id: number;

  @Field(type => String)
  @Column()
  @IsString()
  @Length(5)
  name: string;

  @Field(type => Boolean, { nullable: true }) // GraphQL
  @Column({ default: true }) // Database
  @IsOptional() // TypeScript
  @IsBoolean() // TypeScript
  isVegan: boolean;

  @Field(type => String, { defaultValue: '강남' })
  @Column()
  @IsString()
  address: string;
}

'Uber Eats' 카테고리의 다른 글