[typescript] 마이크로서비스 아키텍처에서 타입스크립트로 데이터베이스 액세스 처리하기

마이크로서비스 아키텍처에서는 각 서비스가 독립적으로 데이터베이스에 액세스하여 데이터를 저장하고 검색해야 합니다. 이를 위해 타입스크립트로 데이터베이스 액세스를 어떻게 처리할 수 있는지 살펴보겠습니다.

1. 데이터베이스 연결 설정

먼저, 타입스크립트로 데이터베이스에 연결하려면 해당 데이터베이스와 상호작용하는 클라이언트 라이브러리를 사용해야 합니다. 예를 들어 PostgreSQL을 사용한다면 pg 모듈을, MongoDB를 사용한다면 mongoose 또는 mongodb 모듈을 사용할 수 있습니다.

// PostgreSQL 연결 설정 예시
import { Client } from 'pg';

const client = new Client({
  user: 'user',
  host: 'localhost',
  database: 'mydatabase',
  password: 'password',
  port: 5432,
});

await client.connect();

2. 데이터베이스 쿼리 실행

데이터베이스에 쿼리를 실행하기 위해서는 해당 데이터베이스에서 제공하는 쿼리 빌더ORM(Object-Relational Mapping)을 사용할 수 있습니다. 이를 통해 타입 안정성(type safety)을 가진 쿼리를 실행할 수 있습니다.

// PostgreSQL에서 일반 SQL 쿼리 실행 예시
const res = await client.query('SELECT $1::text as message', ['Hello world!']);
console.log(res.rows[0].message);

3. 데이터 모델 정의

데이터베이스에서 가져온 데이터를 타입스크립트에서 사용하기 위해 해당 데이터의 모델을 정의해야 합니다. 이때, 인터페이스클래스를 사용하여 정확한 데이터 형식을 정의할 수 있습니다.

// User 모델 정의 예시
interface User {
  id: number;
  username: string;
  email: string;
}

4. 데이터베이스 액세스 레이어 작성

마지막으로, 데이터베이스 액세스를 위한 레이어를 작성하여 서비스에서 데이터베이스와의 상호작용을 캡슐화할 수 있습니다. 이를 통해 서비스 간의 의존성을 줄이고 단위 테스트(unit test)를 쉽게 작성할 수 있습니다.

// User 데이터베이스 액세스 레이어 예시
class UserRepository {
  constructor(private client: Client) {}

  async findUser(id: number): Promise<User | null> {
    const res = await this.client.query('SELECT * FROM users WHERE id = $1', [id]);
    return res.rows[0] ?? null;
  }

  async createUser(username: string, email: string): Promise<User> {
    const res = await this.client.query('INSERT INTO users (username, email) VALUES ($1, $2) RETURNING *', [username, email]);
    return res.rows[0];
  }
}

이와 같이 타입스크립트를 사용하여 데이터베이스 액세스를 처리하면, 코드의 가독성과 유지보수성을 높일 뿐만 아니라 타입 안정성을 확보할 수 있습니다. 때문에 마이크로서비스 아키텍처에서 데이터베이스 액세스를 다룰 때 타입스크립트를 적극적으로 활용하는 것이 권장됩니다.

참고 문헌