※ 当ブログ「日々是事始め(コレコト)」はプロモーションを含みます。
OpenAPI からクライアントを生成できるようになると、つい .vue の中で生成物を直接呼びたくなります。私も最初はそうしていました。でも API 仕様が少し変わっただけで、あちこちの画面を直すはめに。ここで効いてくるのが「生成 API クライアントを画面から直接呼ばない」という設計です。地味ですが、保守のしやすさが段違いになります。
※ 学習用に調べた内容を個人的にまとめたものです。文章は AI の補助を受けて作成しています。
悪い例と良い例
【悪い例】画面が生成物に直結
TaskListPage.vue
↓ 直接呼ぶ
generated/api
【良い例】間に層を挟む
TaskListPage.vue
↓
useTasks.ts(composable)
↓
taskRepository.ts(repository層)
↓
generated/api
ポイントは repository 層。生成された API を「自分のアプリの言葉」で包み直す薄い層です。画面や composable は repository を呼ぶだけで、生成物の存在を知りません。
repository層を書く
// features/tasks/api/taskRepository.ts
import { TasksApi, Configuration } from '@/generated/api'
import type { Task } from '@/generated/api'
const api = new TasksApi(
new Configuration({ basePath: import.meta.env.VITE_API_BASE_URL })
)
export const taskRepository = {
list: async (): Promise<Task[]> => (await api.listTasks()).data,
find: async (id: number): Promise<Task> => (await api.getTask(id)).data,
remove: async (id: number): Promise<void> => {
await api.deleteTask(id)
},
}
もし API のメソッド名やレスポンス構造が変わっても、直すのはこの repository の中だけ。画面や composable は taskRepository.list() のままで済みます。
なぜ包むのか
| メリット | 中身 |
|---|---|
| 影響範囲を閉じ込める | API仕様変更の修正が repository 内で完結する |
| 画面が読みやすい | .vue に通信の詳細が出てこない |
| エラー処理を共通化しやすい | 認証切れ・失敗時の扱いを1か所に |
| テストしやすい | repository を差し替えれば画面のテストが楽 |
| UIライブラリと分離できる | Vuetify などの UI とロジックが混ざらない |
DTOをそのまま画面に出しすぎない
もう1つのコツ。API が返す生のデータ(DTO)を画面の隅々までそのまま流すと、API 変更に画面が引きずられます。表示に必要な形へ repository や composable で整えてから渡すと、画面が API の都合から守られます。最初から完璧にやる必要はありませんが、「画面 → composable → repository → 生成API」の一方向だけは崩さないのがおすすめです。この設計は最終回の CRUD アプリ編でそのまま使います。
もっと体系的に学ぶなら(書籍)
この記事はシリーズの一部です。TypeScript前提で Composition API・Pinia・Vue Router・テストまで一冊で体系的に学びたい方には、内容がそのまま重なる次の本がおすすめです。
PR
📕 紙の本
Vue 3 フロントエンド開発の教科書 [ WINGSプロジェクト 齊藤 新三 ] 価格:3960円 |
📱 電子書籍版
Vue 3 フロントエンド開発の教科書 【電子書籍】[ WINGSプロジェクト 齊藤新三【著】 ] 価格:3960円 |
次に読む



