GRAPHQL

  1. graphql 설치

    • npm i @nestjs/graphql graphql-tools graphql apollo-server-express

      -> Nestjs 방식으로, apollo-server-express 기반으로 작동

  2. controller랑 service 다 지우기

    app.module : main.ts로 import 되는 유일한 모듈

    import { Module } from '@nestjs/common';
    import { GraphQLModule } from '@nestjs/graphql';
       
    @Module({
      imports: [
        GraphQLModule.forRoot()//root module 설정
      ],
      controllers: [],
      providers: [],
    })
    export class AppModule {}
       
    

    -> graphql 은 shema와 resolver 필요

  3. restaurant 모듈( 개념이해를 위해 잠시 만들기)

    • nest g mo restaurants

      • restaurants에 restaurants.resolvers.ts 파일 생성

      • restaurants.resolvers.ts

        import { Query, Resolver } from "@nestjs/graphql";
                
                
        @Resolver()
        export class RestaurantResolver {
            @Query(() => Boolean) //graphql에 return
            isPizzaGood(): Boolean{ //typescript에 return
                return true;
            }
        }
                
        

      => localhost:3000/graphql

    • restaurants에 entities폴더 생성

    • restaurant.entity.ts 생성

      • entities: 데이터베이스에 있는 모델

      • restaurant.entity.ts

        import { Field, ObjectType } from "@nestjs/graphql";
               
               
        @ObjectType()
        export class Restaurant{//Restaurant을 위한 object type 생성
            @Field(is => String)
            name: string;
            @Field(type => Boolean,{nullable:true})
            isGood: boolean;
        }
        
      • restaurant.resolvers.ts

        import { Query, Resolver } from "@nestjs/graphql";
        import { Restaurant } from "./entities/restaurant.entity";
               
               
        @Resolver(of => Restaurant)
        export class RestaurantResolver {
            @Query(returns => Restaurant) //리턴 restaurant
            myRestaurant(){
                return true; //restaurant를 리턴해야하는데 true를 리턴하므로 에러
            }
        }
        

        image

Mutation

  • restaurants.resolver.ts

    • arguments 만들기
      
    import { Args, Query, Resolver } from "@nestjs/graphql";
    import { Restaurant } from "./entities/restaurant.entity";
      
      
    @Resolver(of => Restaurant)
    export class RestaurantResolver {
        @Query(returns => [Restaurant]) //리턴 restaurant array
        restaurants(@Args('veganOnly') veganOnly: boolean): Restaurant[] { //veganOnly라는 argument 호출
            return [];   
        }
    }
    

    image

  • restaurants.resolvers.ts

    • mutaiton

          
      import { Args, Mutation, Query, Resolver } from "@nestjs/graphql";
          
      import { Restaurant } from "./entities/restaurant.entity";
          
          
      @Resolver(of => Restaurant)
      export class RestaurantResolver {
          @Query(returns => [Restaurant]) //리턴 restaurant array
          restaurants(@Args('veganOnly') veganOnly: boolean): Restaurant[] { //veganOnly라는 argument 호출
              console.log(veganOnly)
              return [];   
          }
          
          @Mutation(returns => Boolean)
          createRestaurant(): boolean {
              return true;
          }
      

      image

  • restaurant.entity.ts

    import { Field, ObjectType } from "@nestjs/graphql";
      
      
    @ObjectType()
    export class Restaurant{//Restaurant을 위한 object type 생성
        @Field(is => String)
        name: string;
      
        @Field(type => Boolean)
        isVegan: boolean;
      
        @Field(type => String)
        address:string;
      
        @Field(type => String)
        ownerName:string;
    }
    
  • restaurants.resolver.ts

      
    import { Args, Mutation, Query, Resolver } from "@nestjs/graphql";
      
    import { Restaurant } from "./entities/restaurant.entity";
      
      
    @Resolver(of => Restaurant)
    export class RestaurantResolver {
        @Query(returns => [Restaurant]) //리턴 restaurant array
        restaurants(@Args('veganOnly') veganOnly: boolean): Restaurant[] { //veganOnly라는 argument 호출
            console.log(veganOnly)
            return [];   
        }
      
        @Mutation(returns => Boolean)
        createRestaurant( //arguments 만들기
            @Args('name') name:string,
            @Args('isVegan') isVegan:boolean,
            @Args('address') address:string,
            @Args('ownerName') ownerName:string,
        ): boolean{
            return true;
        }
    }
    

    image

    => 위처럼 argument 하나씩 하는 것보다 InputType으로 한번에 object를 전달하게 하는게 편함(dto랑 비슷)

    InputType

    restaurants에 dtos 폴더 생성 -> create-restaurant.dto.ts 파일 생성

  • create-restaurant.dto.ts

    import { Field, InputType } from "@nestjs/graphql";
      
    @InputType()
    export class CreateRestaurantDto {
        @Field(type => String) //Field는 Type을 필요로 함
        name: string;
        @Field(type => Boolean)
        isVegan: boolean;
        @Field(type => String)
        address: string;
        @Field(type => String) 
        ownerName: string;
    }
    
  • restaurants.resolvers.ts

        @Mutation(returns => Boolean)
        createRestaurant( //arguments 만들기
            @Args('createRestaurantInput') createRestaurantInput: CreateRestaurantDto //한번에 묶기
        ): boolean{
            console.log(createRestaurantInput)
            return true;
        }
    }
    

    image

image ​ -> 위와 같이 써야하는데 불편함

=> InputType을 ArgsType으로 바꾸기

## 	ArgsType
  • create-restaurants.dto.ts

    import { ArgsType, Field, InputType } from "@nestjs/graphql";
      
    @ArgsType() //각각을 분리된 arguments로써 정의 & 분리된 값을 GraphQL argument로 전달
    export class CreateRestaurantDto {
        @Field(type => String) //Field는 Type을 필요로 함
        name: string;
        @Field(type => Boolean)
        isVegan: boolean;
        @Field(type => String)
        address: string;
        @Field(type => String) 
        ownerName: string;
    }
    
  • restaurants.resolver.ts

        @Mutation(returns => Boolean)
        createRestaurant( //arguments 만들기
            @Args() createRestaurantDto: CreateRestaurantDto
        ): boolean{
            console.log(createRestaurantDto)
            return true;
        }
    }
    

image

dto class validators

npm i class-validator

npm i clas-transformer

  • create-restaurant.dto.ts

    import { ArgsType, Field, InputType } from "@nestjs/graphql";
    import { IsBoolean, IsString, Length } from "class-validator";
      
    @ArgsType() //각각을 분리된 arguments로써 정의 & 분리된 값을 GraphQL argument로 전달
    export class CreateRestaurantDto {
      
        @Field(type => String) //Field는 Type을 필요로 함
        @IsString()
        @Length(5, 10)
        name: string;
          
        @Field(type => Boolean)
        @IsBoolean()
        isVegan: boolean;
      
        @Field(type => String)
        @IsString()
        address: string;
      
        @Field(type => String) 
        @IsString()
        @Length(5, 10) //최소 최대 길이 제한
        ownerName: string;
    }
    
  • main.ts

    import { ValidationPipe } from '@nestjs/common';
    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
      
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      app.useGlobalPipes(
        new ValidationPipe() 
      )
      await app.listen(3000);
    }
    bootstrap();
    

    image

    길이 검사해줌