반응형

Repository는 Entity에 대한 CRUD를 추상화한 객체입니다.

여기서 추상화라고 하면,
사용이 복잡한 것들을 핵심적인 기능만 간추려서 사용하기 쉽게 만든 것을 의미합니다.

 

예를 들면,

고양이의 정보를 Database에 저장하기 위해서는 다음과 같은 SQL을 사용합니다.

insert into cat(name, age, breed)
values('꼼지', 5, '스코티시폴드');

 

이것을 Repository 패턴으로 표현하면 다음과 같습니다.

const cat = new CreateCatDto();
cat.name = '꼼지';
cat.age = 5;
cat.breed = '스코티시폴더';
catRepository.save(cat);

SQL을 잘 아는 사람 입장에서는 쿼리를 사용하는 것이 훨씬 가독성이 좋습니다.

하지만 SQL을 잘 모르는 사람도 코딩 방법만 알면 쉽게 Database 핸들링이 가능해집니다.

 

Repository 패턴을 보시면 쿼리를 객체로 만들어서 사용하고 있는 것을 알 수 있습니다.

이렇듯 Repository 패턴은 좀 더 프로그래밍에 가깝게 쿼리를 사용할 수 있게 만든 것입니다.

 

쿼리를 잘 모르거나 간단한 쿼리를 사용하고자 할 경우에는 정말 쉽게 사용을 할 수 있습니다.

 

반응형

'TypeORM' 카테고리의 다른 글

2. TypeORM 사용법 기초 (2023, NestJS)  (2) 2023.05.07
1. TypeORM 개념과 셋팅 (2023, NestJS)  (0) 2023.05.05
반응형

Nestjs의 API를 PUT, POST 등으로 호출할 경우에 보통 Json 형식을 사용하게 됩니다.

이때 json의 용량이 커지게 되면 다음과 같은 문제가 발생합니다.

413 Payload too large

Nestjs의 오류 메시지는 다음과 같습니다.

413 Error in nestjs

이 문제를 해결하는 방법은 main.ts에 다음과 같은 내용을 추가하시면 됩니다.
(app.listen 위에 추가하면 됩니다)

import { json } from 'body-parser';

app.use(json({ limit: '50mb' }));
await app.listen(port);

이 문제의 해결법은 kamilmysliwiec 가 github에서 답변한 내용에서 가져왔습니다.

https://github.com/nestjs/nest/issues/529#issuecomment-376576929

 

How to set limit value for jsonParser · Issue #529 · nestjs/nest

I'm submitting a [ ] Regression [ ] Bug report [x] Feature request [ ] Documentation issue or request [ ] Support request => Please do not submit support request here, instead post your question on...

github.com

 

반응형

'Nestjs 활용팁' 카테고리의 다른 글

NestJS - TypeORM 트랜젝션 처리  (2) 2022.07.29
반응형

반복 작업의 필요성

Schedule이란 일정 주기별로 반복되는 Job을 처리하는 것을 의미합니다.
주기는 다음과 같은 것들이 있을 수 있습니다.

  • 매시, 매일, 매주, 매월, 매년
  • 격주, 격월
  • 특정 시간, 특정 요일, 특정 일자 등등

 

반복되는 작업들은 어떤 것들이 있을까요?

  • 어제의 사이트 통계를 다음날 아침 Slack에 뿌려주기
  • 일주일에 한번 특정 사이트를 크롤링해서 데이터 저장하기
  • 생일인 고객에게 쿠폰을 발행해서 메시지 보내기

이런 작업들을 일일이 수동으로 처리하기는 매우 어렵습니다.

이때 자동화된 스케줄러가 필요합니다.

리눅스의 Crontab

이런 Schedule을 처리하는 대표적인 프로그램이 Linux에서 제공하는 crontab입니다.

리눅스 shell에서 "crontab -e" 명령을 사용하여 편집모드에서 설정을 하게되면,

일정 주기별로 반복 수행하는 형태입니다.

crontab 형식
crontab 샘플

 

AWS 에서 Scheduler 사용하기

Cloud 환경이 되면서 오면서 crontab을 사용하는 것이 어려워졌습니다.

쿠버네티스, AWS ECS등의 도커 기반 오케스트레이션 플랫폼을 사용하게 되면서, 인스턴스의 관리를 사용자가 아닌 플랫폼이 맡게 되기 때문입니다. 이로 인해 사용자가 직접 서버를 수정하는 일이 대부분 사라지게 되었습니다.

 

crontab을 대신할 수 있도록 AWS에서는 Amazon Event Bridge라는 서비스를 제공하고 있습니다.

Amazon EventBridge

Amazon Event Bridge와 AWS Lambda를 조합하면 다양한 구현이 가능합니다.

Amazon Event Bridge + AWS Lambda

 

Amazon EventBridge는 crontab과 거의 유사한 방식으로 aws console에서 구현이 가능합니다.

 

스케줄러 샘플 구현 

Amazon Event Bridge와 Lambda를 이용해 API를 호출하는 서비스를 구현하는 방법을 샘플을 통해 알아봅니다.

순서는 다음과 같습니다.

  • (API를 호출하는) Lambda Function 만들기
  • Amazon EventBridge에 Schedule 등록하기

Lambda Function 만들기

  • AWS Lambda에서 함수를 생성합니다.
  • Python 3.10과 arm을 이용하도록 셋팅합니다.
  • 코드를 다음과 같이 작성합니다.
import json
import requests

def lambda_handler(event, context):
	print('calling...')
	url = "https://api.sample.com/..."
	header = {
		'Content-Type': 'application/json; charset=UTF-8',
		'User-Agent': ...
	}
	res = requests.get(
		url,
		headers,
		data={}
	)
	print(res.content)
	return {
		'statusCode': 200,
		'body': ...
	}
  • requests 라이브러리는 aws에서 기본 제공이 아니기 때문에 Layer를 만들어 추가해 주어야 합니다.
  • Layer는 반드시 python 폴더를 만드시고 해당 폴더에서 pip install로 추가해야 합니다.
mkdir python
cd python

pip install requests -t .
  • python 폴더를 압축합니다. (python.zip)
  • Lambda 메뉴에서 계층을 선택 후 계층 생성 버튼을 클릭합니다.

  • upload에서 python.zip 파일을 추가합니다.

 

Amazon EventBridge에 Scheduler 등록하기

  • Amazon EventBridge 서비스에서 좌측 메뉴의 Scheduler - 일정 메뉴 선택
  • 일정 생성 버튼 클릭
  • cron 형식으로 일정 패턴 등록

  • 대상 선택에서 AWS Lambda를 선택

  • Invoke를 선택하고, 생성한 Lambda function을 선택하면 됩니다.

이렇게 하면 매일 아침 9시에 API를 호출하는 Schedule을 사용할 수 있습니다.

반응형
반응형

이 글은 TypeORM의 기본적인 사용법에 대해 설명합니다.

다음은 이 글을 설명한 유튜브 영상입니다.

https://youtu.be/IfcnR7TtbCw

목차

  • table 생성
  • 소스 생성
  • 사용법

테이블 생성

다음과 같이 cats table을 생성합니다.

create table cat
(
    id    int auto_increment
        primary key,
    name  varchar(255) not null comment '고양이 이름',
    age   int          not null comment '고양이 나이',
    breed varchar(255) not null comment '고양이 종류'
);

소스 생성

  • Nestjs의 Generator(소스 자동 생성)를 사용하여 cats module을 생성합니다.
nest g resource cats
  • resource 옵션은 module, controller, service, entities, dto를 한 번에 자동으로 생성합니다.

Entity 객체 생성

  • domain/cats.entity.ts
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@Entity()
export class Cat {
    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    name: string;

    @Column()
    age: number;

    @Column()
    breed: string;
}

DTO 수정

  • cats/dto/create-cat.dto.ts 를 다음과 같이 만듭니다.
export class CreateCatDto {
    name: string;
    age: number;
    breed: string;
}

모듈에 Entity 임포트

  • cats/cats.module.ts에 cats.entity를 임포트 해주어야 사용할 수 있습니다.
import { Module } from '@nestjs/common';
import { CatsService } from './cats.service';
import { CatsController } from './cats.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Cat } from 'src/domain/cat.entity';

@Module({
  imports: [TypeOrmModule.forFeature([Cat])],
  controllers: [CatsController],
  providers: [CatsService]
})
export class CatsModule {}

서비스에서 Repository 사용하기

cats service에서 constructor에 repository를 주입합니다.

  • cats/cats.service.ts
constructor(
  @InjectRepository(Cat)
  private catRepository: Repository<Cat>
){}
  • cats/cats.service.ts를 다음과 같이 수정합니다.
async create(createCatDto: CreateCatDto) {
  return await this.catRepository.save(createCatDto);
}

async findOne(id: number) {
  return await this.catRepository.findOne({where: {id}});
}

async update(id: number, updateCatDto: UpdateCatDto) {
  const cat = await this.findOne(id);
  if(!cat){
    throw new Error('cat not found');
  }
  Object.assign(cat, updateCatDto);
  return await this.catRepository.save(cat);
}

async remove(id: number) {
  const cat = await this.findOne(id);
  if(!cat){
    throw new Error('cat not found');
  }
  return await this.catRepository.remove(cat);
}

테스트

포스트맨을 사용하여 테스트를 합니다.

  • 생성
    • POST http://localhost:3000/cats
    • Data는 다음과 같습니다.
{
    "name": "엄지",
    "age": 7,
    "breed": "스코티시폴드"
}

  • 전체 목록 조회
    • GET http://localhost:3000/cats

  • 아이디로 조회
    • GET http://localhost:3000/cats/1

  • 업데이트
    • PATCH http://localhost:3000/cats/1
    • Data
{
    "name": "엄지양이",
    "age": 5,
    "breed": "스코티시폴드"
}

  •  삭제
    • DELETE http://localhost:3000/cats/2

이상으로 TypeORM에서 CRUD를 사용하는 방법에 대해서 알아보았습니다.

반응형

'TypeORM' 카테고리의 다른 글

3. TypeORM에서 Repository의 개념 이해하기  (0) 2023.09.12
1. TypeORM 개념과 셋팅 (2023, NestJS)  (0) 2023.05.05
반응형

이 글은 TypeORM의 기본적인 개념에 대해 설명하고, 샘플 소스를 통해 TypeORM의 기본적인 사용법에 대해 설명합니다.

 

이 글의 동영상 강의를 보고 싶으시면 아래를 클릭하세요.

https://youtu.be/yzsN620ZYpw

목차

  • ORM(TypeORM) 개념
  • ORM(TypeORM)의 장단점
  • TypeORM 셋팅하기

 

ORM(TypeORM) 개념

  • TypeORM = "Typescript + ORM"을 의미합니다. 즉, typescript에서 orm을 사용할 수 있도록 만든 프레임워크입니다.
  • ORM은 Object-Relational Mapping의 약자입니다. 
  • Object = 객체지향언어에서 말하는 객체(Object)를 의미합니다.
  • Relational =  관계형 데이터베이스(Relational Database)를 의미합니다.
  • 즉, 객체와 관계형 데이터베이스를 자동으로 맵핑 시켜주는 기술을 ORM이라고 합니다.
  • ORM을 사용하면 DB의 종류에 상관없이 코딩을 할 수 있습니다. 즉, MySQL, PostgreSQL, Oracle등 어떤 Database를 사용하더라도 동일 코드로 작성하여 사용할 수 있도록 만들어진 프레임워크입니다.
  • 결론 : TypeORM은 Typescript에서 사용하는 ORM 프레임워크입니다.

ORM(TypeORM)의 장단점

  • Database의 쿼리문을 사용하는 대신, 기존과 유사한 방식으로 코드를 작성하므로 사용이 편리하다.
  • 독립적인 코드를 사용하므로 재사용성이 증가한다.
  • DBMS에 종속적인 쿼리를 사용하지 않으므로, DB 변경이 용이하다.
  • 테이블간의 관계가 복잡해지고 쿼리가 복잡해질 수록 구현이 어렵다.
  • 쿼리를 많이 사용해본 사람일 경우, 쿼리를 사용했을때 보다 직관성이 떨어진다.

TypeORM 셋팅하기

  • Nestjs 프로젝트를 만듭니다.
nest new typeorm2023
  • TypeORM 관련 패키지를 설치합니다.
npm install --save @nestjs/typeorm typeorm mysql2
  • root 폴더에 orm.config.ts를 만들고 다음과 같이 추가합니다.
import { TypeOrmModuleOptions } from "@nestjs/typeorm";

function ormConfig(): TypeOrmModuleOptions {
    const commonConf = {
        SYNCRONIZE: false,
        ENTITIES: [__dirname + '/domain/*{.ts,.js}'],
        MIGRATIONS: [__dirname + '/migrations/**/*{.ts,.js}'],
        MIGRATIONS_RUN: false,
    };

    return {
        name: 'default',
        type: 'mysql',
        database: 'test',
        host: 'localhost',
        port: Number(3306),
        username: 'root',
        password: 'root',
        logging: true,
        synchronize: commonConf.SYNCRONIZE,
        entities: commonConf.ENTITIES,
        migrations: commonConf.MIGRATIONS,
        migrationsRun: commonConf.MIGRATIONS_RUN,
    };
}

export { ormConfig };
  • 세부사항들을 설명하면 다음과 같습니다.
    • SYNCRONIZE는 객체와 테이블을 동기화 할때 사용합니다. 즉, 객체가 변경되면 테이블에 자동 반영이 되고, 테이블이 변경되면 객체가 자동 변경되는 기능입니다. 이 기능을 운영서버에서 사용할 때는 주의가 필요합니다. 운영중인 데이터는 용량이 크고, 이런 변화가 있을 경우 문제가 생길 수 있으므로, 만약의 사고를 예방하기 위해서는 이 기능을 "false"로 설정하는 것이 좋습니다.
    • ENTITIES는 객체가 위치하는 폴더를 의미합니다. 즉, 테이블의 schema를 객체로 만들어 저장하는 파일들이 위치하는 곳입니다.

 

셋팅이 완료되면 다음과 같이 최상위 모듈에 ormConfig를 추가해 줌으로써 사용이 가능하게 됩니다.

  • app.module.ts에 ormConfig를 추가합니다.
import { ormConfig } from './orm.config';
@Module({
  imports: [
    TypeOrmModule.forRootAsync({ useFactory: ormConfig }),
    ...
  ],
  ...
})

다음은 TypeORM 기초 사용법에 대해 알아보도록 하겠습니다.

반응형

'TypeORM' 카테고리의 다른 글

3. TypeORM에서 Repository의 개념 이해하기  (0) 2023.09.12
2. TypeORM 사용법 기초 (2023, NestJS)  (2) 2023.05.07

+ Recent posts