🧍
ビジネスロジックにフレームワーク固有のコードを含めない
Webアプリケーション開発では、基本的にビジネスロジックにフレームワーク固有のコードを含めることは避けるべきです。これにより、保守性や再利用性が向上し、テストも容易になります。
悪い例:ビジネスロジックにフレームワーク固有のコードを含める
以下の例では、ビジネスロジック内でHono固有の HTTPException
を直接使用して例外を投げています。
import { HTTPException } from 'hono/http-exception';
export function getMiddleCities(cities: CityData[], startCityId: string): CityData[] {
const startIndex = cities.findIndex((city) => city.id === startCityId);
if (startIndex === -1) {
throw new HTTPException(400, { message: "cityId is invalid" });
}
return cities.slice(startIndex);
}
問題点
-
フレームワーク依存
ビジネスロジック内でHono固有のHTTPException
を使用しているため、他のフレームワークでは再利用できません。 -
責務の分離が不十分
ビジネスロジックがHTTPレスポンスの生成を直接扱っており、関心の分離が守られていません。 -
テストが困難
フレームワーク固有の例外がテストを複雑にします。
良い例:ビジネスロジックを分離する
ビジネスロジックをフレームワーク固有の例外から独立させ、純粋なエラーハンドリングを行います。
import { Result, createOk, createErr } from './result'; // 独自のResult型ユーティリティ
export function getMiddleCities(cities: CityData[], startCityId: string): Result<CityData[], Error> {
const startIndex = cities.findIndex((city) => city.id === startCityId);
if (startIndex === -1) {
return createErr(new Error("cityId is invalid"));
}
return createOk(cities.slice(startIndex));
}
フレームワーク固有の例外をエンドポイント側で扱うことで、ビジネスロジックとレスポンス生成を分離します。
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
import { getMiddleCities } from './services/cityService';
const app = new Hono();
app.get('/cities/:startCityId', (c) => {
const cities = [
{ id: '1', name: 'Tokyo' },
{ id: '2', name: 'Osaka' },
{ id: '3', name: 'Nagoya' },
];
const startCityId = c.req.param('startCityId');
const result = getMiddleCities(cities, startCityId);
if (result.isErr()) {
throw new HTTPException(400, { message: result.error.message });
}
return c.json({ cities: result.value }, 200);
});
export default app;
メリット
-
フレームワーク非依存
ビジネスロジックがフレームワークに依存していないため、再利用性が向上します。 -
責務の分離
HTTPレスポンス生成やエラーハンドリングはエンドポイントで処理され、ビジネスロジックは純粋に動作します。 -
保守性向上
フレームワーク変更した場合でも影響を最小限に抑えることができます。 -
テスト容易性
純粋なビジネスロジックをテストすることで、エラー処理やロジックの検証が容易になります。
結論
このように、ビジネスロジックをフレームワーク固有のコードから分離することで、柔軟でメンテナブルなコードベースを実現できます。
Discussion