TypeScriptとNode.jsを使った効率的なAPI開発環境の構築

TypeScript, Node.js, Expressを用いたAPI開発は非常に一般的であり、開発環境と本番環境で異なるデータベースを使うことにより、効率的な開発フローが可能になります。ここでは、SQLiteを開発環境で、MySQLを本番環境で使用するセットアップ方法について説明します。

### 環境情報

このセットアップは、以下のバージョンのNode.jsとnpmが前提となります。

- Node.js: v20.12.1
- npm: 10.5.0

### 1. プロジェクトの初期設定

まずは、Node.jsプロジェクトの基盤を作成し、必要なライブラリをインストールします。

```bash
mkdir my-api-project
cd my-api-project
npm init -y
npm install express typescript ts-node @types/node @types/express
npm install sqlite3 mysql2
npm install typeorm reflect-metadata  # ORMライブラリ
```

### 2. TypeScript の設定

プロジェクトのルートにTypeScriptの設定ファイルを作成します。

```bash
cat << EOF > tsconfig.json
{
  "compilerOptions": {
    "target": "es2020",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "esModuleInterop": true,
    "strict": true,
    "types": ["reflect-metadata"],
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
EOF
```

### 3. データベース設定

TypeORMを活用し、環境に応じてSQLiteまたはMySQLを使用するように設定します。

srcフォルダを作成して、その中にDBの設定ファイルを作成します。
```bash
mkdir src
```

```typescript
cat << EOF > src/database.ts
import { DataSource } from "typeorm";

const AppDataSource = new DataSource({
  type: process.env.NODE_ENV === "production" ? "mysql" : "sqlite",
  database:
    process.env.NODE_ENV === "production" ? "prod_db_name" : "database.sqlite",
  entities: [],
  synchronize: true,  // 本番環境ではfalseにすることを推奨
});

export const databaseInit = async () => {
  try {
    await AppDataSource.initialize();
    console.log("Database connection established.");
  } catch (error) {
    console.error("Database connection failed:", error);
  }
};
EOF
```

**注意点:** `synchronize: true`は開発中には便利ですが、本番環境での使用は推奨されません。適切なデータベースマイグレーション戦略を採用してください。

### 4. Express アプリケーションのセットアップ

Expressで基本的なWebサーバーを構築し、簡単なルートを定義します。

```typescript
cat << EOF > src/app.ts
import express from 'express';
import { databaseInit } from './database';

const app = express();
app.use(express.json());

databaseInit().then(() => {
  console.log('Database connected.');
}).catch(error => {
  console.error('Database connection failed:', error);
});

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});
EOF
```

### 5. プロジェクトの実行

開発をスムーズに進行させるために、`"start": "ts-node src/app.ts"`のスクリプトを`package.json`に追加し、サーバーを起動します。

```json
"scripts": {
  "start": "ts-node src/app.ts",
  "test": "echo \"Error: no test specified\" && exit 1"
}
```
`npm start`コマンドでサーバーを起動後、ブラウザでhttp://localhost:3000/ を開き`Hello World!`の表示を確認してください。
```bash
npm start
```
停止は、Ctrl + C キーを押すことでプロセスを停止できます。

この基本セットアップをもとに、APIのエンドポイントを拡張し、新たなエンティティを追加し、ビジネスロジックを組み込むことで、開発の柔軟性を高めていくことができます。

### 補足. 一般的なディレクトリ構成

```
my-api-project/
├── src/
│   ├── config/            # 設定ファイルや環境依存の設定
│   ├── controllers/       # ルートコントローラー
│   ├── entities/          # TypeORMエンティティ
│   ├── middleware/        # Expressミドルウェア
│   ├── services/          # ビジネスロジック
│   ├── utils/             # ユーティリティ関数
│   └── app.ts             # アプリケーションのエントリーポイント
├── dist/                  # TypeScriptのコンパイル後のJavaScriptファイル
├── node_modules/          # npmパッケージ
├── .env                   # 環境変数
├── ormconfig.json         # TypeORM設定
├── package.json           # プロジェクトメタデータと依存関係
├── tsconfig.json          # TypeScript設定
└── README.md              # プロジェクトの説明

```