メインコンテンツまでスキップ

Node.jsではじめる

このガイドでは、Node.js上でZeltアプリケーションをゼロから構築する手順を説明します。

前提条件

  • Node.js v20以上(またはBun v1.0以上)
  • パッケージマネージャ: pnpm(推奨)、npm、またはbun

インストール

pnpm add @zeltjs/core @zeltjs/adapter-node

プロジェクト構成

my-app/
├── src/
│   ├── entry/
│   │   ├── controllers/    # HTTPエンドポイント
│   │   └── commands/       # CLIコマンド
│   ├── services/           # ビジネスロジック
│   ├── configs/            # 設定クラス
│   ├── app.ts              # アプリケーション定義
│   ├── cli.ts              # CLIエントリポイント
│   └── main.ts             # HTTPサーバーエントリポイント
├── package.json
└── tsconfig.json
ディレクトリ用途
entry/外部向けエントリポイント(HTTP、CLI)
services/ビジネスロジック、DIで注入される
configs/環境変数と設定

Hello World

Step 1: Controllerを作成する

Controllerは受信したHTTPリクエストを処理し、レスポンスを返します。各controllerは @Controller でデコレートされたクラスで、ルートのprefixを定義します。

src/entry/controllers/hello.controller.ts を作成します:

@Controller('/hello')
export class HelloController {
  @Get('/:name')
  greet(req = request()) {
    const name = req.pathParam('name');
    return { message: `Hello, ${name}!` };
  }
}
  • @Controller('/hello') — このcontroller内の全ルートの基本パスを設定します
  • @Get('/:name')/hello/:name へのGETリクエストを処理します
  • req.pathParam('name') — URLパスから name パラメータを取り出します

Step 2: アプリケーションを作成する

src/app.ts を作成し、controllerを結線してNode.jsランタイム用に準備します:

export const app = createApp([http({
    controllers: [HelloController],
  })]);

export default await onNode(app);

onNode() 関数はアプリをNode.jsランタイム用に準備し、http.listen()get()args プロパティを持つ NodeApp を返します。

Step 3: サーバーを起動する

サーバーを起動するために src/main.ts を作成します:

const server = await nodeApp.http.listen({ port: 3000 });
console.log(`Server running at http://localhost:${server.address.port}`);

Step 4: TypeScriptを設定する

tsconfig.json を作成します:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src"]
}

Step 5: アプリケーションを実行する

npx tsx src/main.ts

http://localhost:3000/hello/world にアクセスすると、次のように表示されます:

{ "message": "Hello, world!" }

Serviceを追加する

Serviceはビジネスロジックを持ち、controllerへ注入できます。クラスをserviceとしてマークするには @Injectable を使います。

src/services/greeting.service.ts を作成します:

@Injectable()
export class GreetingService {
  greet(name: string): string {
    return `Hello, ${name}!`;
  }
}

serviceを使うようcontrollerを更新します:

@Controller('/hello')
export class HelloController {
  constructor(private greetingService = inject(GreetingService)) {}

  @Get('/:name')
  greet(req = request()) {
    const name = req.pathParam('name');
    return { message: this.greetingService.greet(name) };
  }
}

設定

Zeltは環境変数を管理するための設定クラスを提供します。

環境変数を使う

@Controller('/config')
export class ConfigController {
  constructor(private env = inject(Env)) {}

  @Get('/api-host')
  getApiHost() {
    return { apiHost: this.env.getString('API_HOST', 'localhost') };
  }
}

onNode() はenv adaptorを自動で登録するため、inject(Env) は追加設定なしに process.env から読み取ります。.env ファイルを使う場合は、entryポイントで dotenv/config をimportしてください。

次のステップ

基本的なアプリケーションが動くようになったので、他の機能も見てみましょう:

  • Controllers — ルーティングとHTTPメソッド
  • Services — ビジネスロジックと依存性注入
  • Validation — Valibotによるリクエストボディのバリデーション
  • Middleware — リクエスト/レスポンスのインターセプタ
  • Configuration — 高度な設定パターン