@nestjs/graphql 데코레이터 정릐

캡틴 노드랭크·2021년 9월 21일
0

NestJS

목록 보기
3/5
post-thumbnail

DTO?

DTO(Data Transfer Object), 데이터를 오브젝트로 변환하는 객체라는 뜻으로, 각 계층(Controller, View 등) 간의 데이터 교환을 위한 객체를 말한다.

dto를 활용하려는 목적은 ClassInterface를 통해 데이터를 유효성 검증하기 위해 사용한다.

  • ClassInterface를 활용한 DTO 검증
export class createTestDTO {
  readonly name: string;
  readonly age: number;
  readonly location: string[];
}
  • class-validator로 활용가능

import { IsNumber, IsString } from 'class-validator';

export class createTestDTO {
  @IsString()
  readonly name: string;
  @IsNumber()
  readonly age: number;
  @IsString({ each: true })
  readonly location: string[];
}
  • 혹은 이런 방법으로 사용

import { Field, InputType, Int } from '@nestjs/graphql';
import { IsNotEmpty, IsEmail } from 'class-validator';

@InputType()
export class CreateUserInput {
  @Field()
  @IsNotEmpty()
  @IsEmail()
  email: string;

  @Field(() => Int)
  @IsNotEmpty()
  age: number;
}

DTO VS ENTITY

EntityDTO는 엄연히 분리해서 관리해야한다.

DB LayerView Layer 사이의 역할을 분리하기 위해서이다.

DTO 클래스는 View(클라이언트)와 통신하기 때문에 자주 변경되는 한편

Entity 클래스는 실제 테이블과 매핑되어, 변경되면 여러 다른 클래스에 영향을 끼친다.

NestJS 에서 TypeScript로만 작성하고자 할때

클래스 상단에 사용

ObjectType()

@ObjectType() 

스키마(Scheme) 정의의 대부분은 객체유형(Obejct Type)이다.
정의하는 각 객체 유형은 클라이언트가 상호 작용해야하는 도메인 객체를 나타내야한다.

스키마 우선 접근방식

type Author {
  id: Int!
  firstName: String
  lastName: String
  posts: [Post]
}

코드 우선 접근 방식

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Post } from './post';

@ObjectType()
export class Author {
  @Field(type => Int)
  id: number;

  @Field({ nullable: true })
  firstName?: string;

  @Field({ nullable: true })
  lastName?: string;

  @Field(type => [Post])
  posts: Post[];
}

InputType()

@InputType()

DTO를 사용하는 Resolver@Args('')에 해당 객체에 대한 이름을 반드시 넣어주어야한다.

@InputType()를 사용했을 경우 @Args()는 명시된 객체가 들어오고, DTO로 명시해준 타입에 맞게 들어온다.

  • 예시
  @Mutation(() => User)
  createUser(@Args('createUserData') createUserData: CreateUserInput): User {
    return this.usersService.createUser(createUserData);
  }

ArgsType()

@ArgsType()

DTO@Args()에 이름을 넣어줄 필요는 없다.

@ArgsType()를 사용했을때, Resolver는 여러개의 인자를 받게된다.

  • 예시
import { ArgsType, Field } from '@nestjs/graphql';
import { IsArray } from 'class-validator';

@ArgsType()
export class GetUsersArgs {
  @Field(() => [String])
  @IsArray()
  userIds: string[];
}
  @Query(() => [User], { name: 'users', nullable: 'items' })
  getUsers(@Args() getUsersArgs: GetUsersArgs): User[] {
    return this.usersService.getUsers(getUsersArgs);
  }

Injectable

@Injectable()

Resolver

@Resolver()

Controller

@Controller()

클래스 내부에 사용

Field

@Field()

필드를 작성해줄 때 사용한다. 선택적 유형 함수 선태적 옵션으로 원하는 GraphQL유형을 반환할 수 있다.

  • A.예시: 어떤 필드가 정수만 반환하기 원할경우.
@Field(type => Int)
id: number;

또는

@Field(type => Float)
id: number;
  • B.예시: 어떤 필드가 배열인 경우.
@Field(type => [Item])
cart: Item[];

또는

@Field(type => [String])
id: string[];
  • B-1.예시: 배열의 항목이 nullable임을 선언 할 경우
@Field(type => [Item], { nullable: 'item'})
cart: Item[];
  • B-2.예시: 배열과 항목 모두 nullable 일 경우
@Field(type => [String], { nullable: 'itemsAndList'})

Resolver

@Resolver()

Resolover는 클라이언트와 상호 작용할 수 있게 도와주는 데코레이터이다.

작성 방법은 대략 아래와 같다.

  • A.예시: User라는 클래스를 사용할때.
@Resolver(() => User)
export class UsersResolver {
  constructor(
    private readonly usersService: UsersService){}
  )
}

  @Query(() => User)
  getUser(@Args() getUserArgs: GetUserArgs): User {
    return this.usersService.getUser(getUserArgs)
  }

  @Mutation(() => User)
    createUser(@Args('createUserData')   createUserData: CreateUserInput): User {
      return this.usersService.createUser(createUserData);
  }

Query

@Query()

Mutation

@Mutation

Args

@Args()

Int

@Int

profile
다시 처음부터 천천히... 급할필요가 없다.

0개의 댓글