Entity & Repository

김민재·2021년 11월 28일
0

Nest.JS & graphQl

목록 보기
4/7

*🔐Study Keyword :

🔑Entity & 🗝️Repository를 생성해보고 연결해보자

1. Entity

  • DataBase 테이블에 매핑되는 클래스를 의미한다.
  • TypeORM의 Entity는 GraphQl에서 사용하는 Entity와 굉장히 유사하다.

GraphQl에서 사용하는 Entity

  • @ObjectType()은 GraphQl에서 자동으로 스키마를 빌드하기 위해 사용하는 GraphQl decorator이다.
import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType()
export class Restaurants {
  @Field((type) => String)
  name: string;
  @Field((type) => Boolean, { nullable: true })
  isVegan?: boolean;
  @Field((type) => String)
  address: string;
  @Field((type) => String)
  ownerName: string;
}

TypeORM의 Entity와 함께 사용

  • @Entity()은 TypeORM이 DB에 저장해주도록 도와준다.
    -@Entity() @Column() 데코레이터를 활용하여 클래스 하나로 GraphQl 스키마와 DB에 저장되는 실제 데이터의 형식을 만들 수 있다.

Restaurants.entity.ts

import { Field, ObjectType } from '@nestjs/graphql';
import { Column, Entity } from 'typeorm';
@ObjectType()
@Entity()
export class Restaurants {
   @PrimaryGeneratedColumn()
  @Field((type) => Number)
  id: number;
  @Field((type) => String)
  @Column()
  name: string;
  @Field((type) => Boolean, { nullable: true })
  @Column()
  isVegan?: boolean;
  @Field((type) => String)
  @Column()
  address: string;
  @Field((type) => String)
  @Column()
  ownerName: string;
}
  1. TypeORM에 만든 Entity가 어디 있는지 알려준다.
  • TypeormModule에 넣는 entities에 배열로 Entity를 넣어준다.

app.module.ts

import { Module } from '@nestjs/common';
import * as Joi from 'joi';
// 자바스크립트 패키지는 타입스크립트로 만들어있지 않기때문에 import하는 방식이 다름
import { ConfigModule } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import { TypeOrmModule } from '@nestjs/typeorm';
import { RestaurantsModule } from './restaurants/restaurants.module';
import { Restaurants } from './restaurants/entities/restaurants.entity';
@Module({
  imports: [
    TypeOrmModule.forRoot({
      // TypeormModule에 Restaurants라는 entity를 가지면 Restaurant이 DB가된다.
      entities: [Restaurants],
      type: 'postgres',
      host: process.env.DB_HOST,
      port: +process.env.DB_PORT,
      username: process.env.DB_USERNAME,
      password: process.env.DB_PASSWORD,
      database: process.env.DB_NAME,
      synchronize: process.env.NODE_ENV !== 'prod',
      // prod 아니면 synchronize가 true
      logging: true,
    }),
    ,
  ],
})

-GraphQl에서 사용하는 스키마를 자동으로 생성해주고 TypeOrmModule에서 imports하는 Entity로 인해 DB에 즉시 반영된다.

2. Repository

-TypeOrm을 이용, TypeOrmModule에 존재하는 Repository를 이용해서 DB에 있는 테이블에 접근하기
DB와 상호작용하는데 있어서 쓰는 패턴
1번. Active Record - 소규모 앱애서 단순하게 사용하기 좋다
TyeOrm에서 이 패턴을 사용하기 위해서는 Entity를 BaseEntity로 extends해줘야한다.

import {BaseEntity, Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity()
export class User extends BaseEntity {
    @PrimaryGeneratedColumn()
    id: number;
    @Column()
    firstName: string;
    @Column()
    lastName: string;
    @Column()
    isActive: boolean;
}
// example how to save AR entity
const user = new User();
user.firstName = "Timber";
user.lastName = "Saw";
user.isActive = true;
await user.save();
// example how to remove AR entity
await user.remove();
// example how to load AR entities
const users = await User.find({ skip: 2, take: 5 });
const newUsers = await User.find({ isActive: true });
const timber = await User.findOne({ firstName: "Timber", lastName: "Saw" });

2번. Data Mapper - 유지 관리하는 것을 도와주고 대규모 앱에서 유용한다.
Entity와 실제 상호작용을 담당하는 Repository가 필요하다

  • Nest.js+TypeOrm 개발 환경에서는 Repository를 자동으로 사용해주는 클래스, 모듈을 쓸 수 있기에 Data Mapper 패턴을 사용한다,

3. Injecting The Repository

Data Mapper stype

  1. TypeOrm을 이용해서 Restaurants repository를 import한다.
  • TypeOrmModule.forFeature에 배열 형태로 entity 클래스들을 넣기
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Restaurants } from './entities/restaurants.entity';
import { RestaurantsResolver } from './restaurants.resovler';
import { RestaurantService } from './restaurants.service';
@Module({
  imports: [TypeOrmModule.forFeature([Restaurants])],
  // forFeature을 활용하면 TypeOrmModule가 특정 feature(Restaurant entity)를 import할 수 있음
  providers: [RestaurantsResolver, RestaurantService],
})
export class RestaurantsModule {}
  1. RestaurantService에서 repository를 사용하기 위해선 RestaurantService에서 RestaurantsResolver에서 import하기
    -주의) Restaurantservice가 providers에 추가 되어있어야한다.
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
import { CreateRestaurantDto } from 'src/dtos/create-restaurant.dto';
import { Restaurant } from './entities/restaurant.entity';
import { RestaurantService } from './restaurants.service';
@Resolver((of) => Restaurant)
export class RestaurantsResolver {
  //Injectable 한 RestaurantService를 RestaurantResolver에서 import하기 
  constructor(private readonly restaurantService: RestaurantService) {}
  @Query((returns) => [Restaurant])
  myRestaurant(): Promise<Restaurant[]> {
  //RestaurantService를 import하면 restaurantService 사용할 수 있음
    return this.restaurantService.getAll();
  }
  @Mutation((returns) => Boolean)
  createRestaurant(@Args() createRestaurantDto: CreateRestaurantDto): boolean {
    console.log(createRestaurantDto);
    return true;
  }
}
  1. Injectable 데코레이터로 서비스를 파일을 만들어준다.
    주의) RestaurantService에서 repository를 사용하기 위해서 service를 resolver에서 import 하고 있어야한다.
  2. 그리고 module에서 import한 Restaurant entity의 repository를 inject한다.
  • InjectRepository()안에 entity이름, Restaurant을 넣어서 호출한다.
  • 이렇게하면 this.restaurants.하면 repository에 쓸 수 있는 모든 옵션들에 접근해 사용 할수 있다.
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';
import { Restaurant } from './entities/restaurant.entity';
@Injectable()
export class RestaurantService { 
  // repository는 이름이 restaurants이며 Restaurant entity(class)의 Repository이다.
  constructor(
    @InjectRepository(Restaurant)
    private readonly restaurants: Repository<Restaurant>,
  ) {}
  getAll(): Restaurant[] {
    return this.restaurants.find()
  }
}

*💡conclusion

  • TypeORM(entity)를 graphQL의 ObjectType 옆에 쓰기만하면 DB에 모델을 생성하고 자동으로 graphQL에 스키마를 작성할 수 있고 graphQL 쿼리와 뮤테이션을 사용할 수 있는 resolver도 사용할 수 있다.
  • 생성한 Repository는 service에 연결되며 이 service가 DB에 접근할 수 있다.

#📑Study Source

  • 니꼴라스 쌤의 우버이츠 강의 중
profile
자기 신뢰의 힘을 믿고 실천하는 개발자가 되고자합니다.

0개의 댓글