본문 바로가기

[Nextjs]Vercel + TypeORM

@Jeeqong 2024. 9. 5. 11:38
반응형

서론

TypeORM을 사용할 때는 몇 가지 필수 패키지를 설치해야 합니다. 특히 Vercel과 연결되어 있다면 TypeORM과 PostgreSQL을 함께 사용하는 환경에서 필수적인 패키지를 설치하고 설정해야 합니다. 아래는 TypeORM을 설정할 때 필요한 것들입니다.

본론

1. 필수 패키지 설치

TypeORM을 프로젝트에서 사용하려면 다음과 같은 패키지를 설치해야 합니다.

npm install typeorm reflect-metadata pg

 

설명:

  • typeorm: TypeORM 라이브러리.
  • reflect-metadata: TypeORM에서 데코레이터를 사용하기 위한 메타데이터 패키지 (반드시 import해야 함).
  • pg: PostgreSQL을 사용할 경우 필요한 PostgreSQL 드라이버.

2. Vercel에서 PostgreSQL 연결

Vercel에 연결된 PostgreSQL 데이터베이스가 이미 설정되어 있는 상태라면, 환경 변수를 통해 데이터베이스 연결 정보를 TypeORM에 제공해야 합니다. 보통 DATABASE_URL로 Vercel에서 PostgreSQL 연결 정보를 설정할 수 있습니다.

Vercel 환경변수 설정:

DATABASE_URL=postgres://username:password@host:port/dbname

3. TypeORM 설정 파일

TypeORM을 사용하려면 ormconfig.js 또는 ormconfig.json 파일을 생성하거나, 프로그램 코드에서 설정할 수 있습니다. Vercel과의 호환을 위해 환경 변수를 사용하는 설정 방식을 권장합니다.

ormconfig.js 예시 (환경 변수를 사용하는 방식):

module.exports = {
  type: 'postgres',
  url: process.env.DATABASE_URL, // Vercel의 환경 변수를 사용
  synchronize: true, // 개발 중에는 true, 운영 환경에서는 false로 설정
  logging: true,
  entities: ['models/**/*.ts'], // 엔티티 파일 경로
};
 

4. Reflect Metadata Import

TypeORM을 사용할 때는 reflect-metadata를 프로젝트의 진입점(index.ts 또는 server.ts)에서 반드시 import해야 합니다.

import 'reflect-metadata';

5. Vercel과 TypeORM의 고려 사항

  • 데이터베이스 연결 최적화: Vercel의 서버리스 환경에서는 짧은 수명의 함수 호출로 인해 데이터베이스 연결을 유지하는 것이 어려울 수 있습니다. 이를 해결하기 위해, Vercel의 serverless functions에서 데이터베이스 연결을 최소화하거나, pg 드라이버에서 연결 풀을 사용하여 관리할 수 있습니다.
  • 예시: 데이터베이스 연결 풀 사용
import { createConnection } from 'typeorm';

let connection;

export async function getConnection() {
  if (!connection) {
    connection = await createConnection();
  }
  return connection;
}

6. TypeORM을 Vercel 환경에서 사용하는 요약

  1. 필수 패키지 설치: typeorm, reflect-metadata, pg 설치.
  2. Vercel 환경변수 설정: DATABASE_URL로 PostgreSQL 연결 정보 제공.
  3. TypeORM 설정 파일: ormconfig.js 또는 코드 내에서 환경 변수 기반 설정.
  4. Reflect Metadata 사용: 프로젝트 진입점에서 reflect-metadata를 import.
  5. Vercel 서버리스 환경 대응: 연결 풀 또는 최소한의 연결 관리를 통해 최적화.

이렇게 설정하면 TypeORM을 Vercel의 PostgreSQL과 잘 연동하여 사용할 수 있습니다.


7. 연결 풀 설정

  • DataSource를 사용하여 PostgreSQL과 연결을 설정하고, 연결 풀(pool) 옵션을 적용합니다.

DataSource 설정 코드 예시

TypeORM의 DataSource를 정의하고, 연결 풀을 설정합니다.

// lib/data-source.ts
import { DataSource } from 'typeorm';
import { User } from '@/models/user'; // 예시 엔티티

// DataSource 생성
export const AppDataSource = new DataSource({
  type: 'postgres',
  url: process.env.DATABASE_URL, // Vercel 환경 변수 사용
  entities: [User], // 엔티티들 등록
  synchronize: true, // 개발 중에만 true, 배포 시 false로 변경
  logging: true,
  extra: {
    max: 10, // 연결 풀에서 유지할 최대 연결 수
    idleTimeoutMillis: 30000, // 유휴 상태일 때 연결을 끊는 시간 (밀리초)
  },
});

// 연결 초기화 함수
export async function initializeDataSource() {
  if (!AppDataSource.isInitialized) {
    await AppDataSource.initialize();
  }
  return AppDataSource;
}

 

 

models/user.ts:

  • 데이터베이스의 User 엔티티를 정의
// models/user.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

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

  @Column()
  name: string;

  @Column({ unique: true })
  email: string;

  @Column()
  password: string;
}

 

services/authService.ts:

  • 인증 관련 비즈니스 로직을 처리하는 파일입니다. 예를 들어, 로그인 시 사용자 정보 조회 및 비밀번호 검증을 처리합니다.
// services/authService.ts
import { AppDataSource } from '@/lib/data-source';
import { User } from '@/models/user';

export async function getUserByEmail(email: string) {
  const userRepository = AppDataSource.getRepository(User);
  return await userRepository.findOne({ where: { email } });
}

 

pages/api/auth/login.ts:

  • Next.js의 API 라우트에서 로그인 API를 처리하는 파일입니다.
  • **authService**에서 가져온 비즈니스 로직을 사용해 사용자 인증을 처리합니다.
// pages/api/auth/login.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { getUserByEmail } from '@/services/authService';
import bcrypt from 'bcryptjs';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: 'Method Not Allowed' });
  }

  const { email, password } = req.body;

  try {
    const user = await getUserByEmail(email);
    if (!user) {
      return res.status(401).json({ message: 'Invalid email or password' });
    }

    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      return res.status(401).json({ message: 'Invalid email or password' });
    }

    return res.status(200).json({
      id: user.id,
      email: user.email,
      name: user.name,
    });
  } catch (error) {
    return res.status(500).json({ message: 'Something went wrong', error: error.message });
  }
}

 

8. 폴더 구조

  • 폴더 구조를 기능별로 나누어 유지보수성을 높일 수 있습니다. lib/, models/, services/ 같은 폴더를 사용하여 데이터를 관리하고 비즈니스 로직을 처리합니다.
project-root/
│
├── lib/
│   └── data-source.ts    # DataSource 설정 파일
│
├── models/
│   └── user.ts           # 사용자 엔티티 정의 (User 엔티티)
│
├── services/
│   └── authService.ts    # 인증 관련 비즈니스 로직 (로그인, 회원가입 등)
│
├── pages/
│   └── api/
│       └── auth/
│           └── login.ts  # 로그인 API 엔드포인트
│
└── .env                  # Vercel 환경 변수 파일

 

반응형
Jeeqong
@Jeeqong :: JQVAULT

Jeeqong's vault : 정보/기록을 쌓아두는 공간 웹개발 포스팅 일상 리뷰를 기록하는 공간입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차