nestJS로 개인프로젝트만들기8

Parker.Park·2022년 8월 23일
0

personal_project1

목록 보기
8/9

Sequelize를 활용한 CRUD

이어서 Sequelize를 활용해서 CRUD를 만들어보자. 여전히 고민인것이 GraphQL이다. ORM은 곧장 따라서 하는 것같은데 GraphQL관련해서는 아직도 수업시간에 배운것을 못벗어 나는 경우가 많다. 데코레이터 하나에 대해서 오래 고민하게 된다. 어쩌면 이것이 타입스크립트가 부족한 것인지도 모르겠다. 메소드들의 도움말이나 클릭 이후에 들어가면 이해가 곧잘 된적은 많지 않기 때문이다.

dto 생성

지난 시간 CRUD중 , CR만 만들었다. 이번에 upate와 delete api를 만들어보려고 한다. 어떤 항목을 업데이트 할 것인지 entity를 참고해야한다.

//user.entity.ts

import { Field, ObjectType } from '@nestjs/graphql';
import {
  Column,
  CreatedAt,
  DataType,
  DeletedAt,
  Model,
  Table,
  UpdatedAt,
} from 'sequelize-typescript';

@Table
@ObjectType()
export class User extends Model<User> {
  @Column({
    type: DataType.CHAR(36),
    defaultValue: DataType.UUIDV4,
    primaryKey: true,
  })
  @Field(() => String)
  id: string;

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

  @Column
  @Field(() => String)
  phone: string;

  @Column
  @Field(() => String)
  email: string;

  @CreatedAt
  @Field(() => Date)
  creationDate: Date;

  @UpdatedAt
  @Field(() => Date)
  updatedOn: Date;

  @DeletedAt
  @Field(() => Date)
  deletionDate: Date;
}

여러 필드가 있지만 그 중에서 name, phone, email만 뽑고, 이 중에서 입력된 내용만 바꾸고 싶을 것이다. 또한 return type은 User타입 그대로 가져오고 싶었다.
처음에는 Args decorator를 이용하려고 했으나, 항상 서비스가 커질 수도 있다는 마음가짐으로 InputType으로 만들려고 한다.

Partial

Partial은 여러 요소중 optional하게 데이터를 선택하여 입력하는 것이다.
하지만 위에 User.entity중 name, phone, email외에는 인자로 받을 필요가 없다.
또한 Nest에서 제공하는 Partial은 TypeScript에서 나오는 Partial과는 달리 InputType을 인자로 받기 때문에 InputType을 굳이 만들어줘야 한다.(작게 만드는거에 비해서 손이 많이 가는거 같다.)

//createUserInput.ts

import { Field, InputType } from '@nestjs/graphql';

@InputType()
export class CreateUserInput {
  @Field(() => String)
  name: string;

  @Field(() => String)
  phone: string;

  @Field(() => String)
  email: string;
}

이렇게 만든 InputType은 모두 필수값이기에 Update할 요소는 optional하게 받기위해 Partial을 상속 받을 것이다.
현재는 createUserInput 클래스가 원하는 세 인자가 있기때문에 그대로 Partial을 하겠으나, 더 많을 경우는 Pick을 사용하여야 한다. 아래 타입스크립트에 대해서 참고 바란다.
Pick, Partial에 대한 TypeScirpt

//updateUserInput.ts

import { InputType, PartialType } from '@nestjs/graphql';
import { CreateUserInput } from './createUserInput';

@InputType()
export class UpdateUserInput extends PartialType(CreateUserInput) {}

NestJS - Sequelize ORM : update, delete

//user.service.ts

import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './models/user.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectModel(User)
    private userModel: typeof User,
  ) {}
  
  //update
 async update({ id, updateuserInput }) {
    const updatedUser = await this.userModel.findOne({ where: { id } });
    if (!updatedUser)
      throw new BadRequestException('업데이트할 데이터가 없습니다.');
    updatedUser.set({ ...updateuserInput });

    return await updatedUser.save();
  }

  //delete
  async delete({ id }) {
    const result = await this.userModel.destroy({ where: { id } });
    return result;
  }
  
  
}

처음에는 Sequelize docs와 Git hub를 참조하였다.
'update' 메소드는 return 값이 원하는 타입이 아니었고, .then으로 하는 방식은 자주 쓰는 방식이 아니라 docs에 있는 것을 참조 하였다.
docs에는 create한 다음 바꾸는 형식이 있었는데 이유는 모르겠으나 create하면 sql에서는 insert로 넘어가서 findOnde으로 객체를 받아온다음 set을 사용하였다. 이게 정확하게 맞는지는 모르겠당.
delete는 simple delete라고 하여 참고 하였다.

마치면서

TypeScirpt와 Mysql에 대한 지식이 더 필요하다는 것을 느꼈다.

참조

Resolvers, NestJS Docs

Mutations, NestJS Docs

Mapped types, NestJS Docs

Model Instances, Sequelize Docs

Simple DELETE queries, Sequelize Docs

sequelize-typescript, Sequelize Github

profile
개발자준비중

0개의 댓글