APIのバージョニングとページネーション — 大量データを扱う設計テクニック
バイブコーディング入門 — 第14回
前回のおさらいと、今回のテーマ
前回(第13回)では、リソース設計の実践をやった。業務フローから名詞を拾い出し、各リソースのフィールドを決め、親子関係と参照関係を整理する。この3ステップで、AIに伝わるデータ構造を自分で設計できるようになった。
今回のテーマは、アプリのデータが増えてきたときに必要になる2つの設計テクニックだ。
1つ目は「ページネーション」。一覧画面のデータが100件、1,000件と増えたとき、全部を一度に読み込むとアプリが遅くなる。ページ送りで分割して表示する仕組みだ。
2つ目は「バージョニング」。APIの仕様を変えたいとき、すでに動いている画面を壊さないようにする仕組みだ。
どちらも、バイブコーディングでAIにアプリを作ってもらい、実際に運用し始めると遭遇する課題だ。最初は50件だったデータが半年後には3,000件になる。最初のAPI設計では足りない機能が出てくる。そのとき慌てないための知識を、この記事で身につけよう。
ページネーションとは — 電話帳のページ送り
ページネーション(pagination)とは、大量のデータを「ページ」に分けて少しずつ取得する仕組みだ。日本語では「ページ送り」「ページ分割」とも呼ぶ。
身近な例で考えてみよう。あなたの会社の顧客リストが3,000件あるとする。これを一覧画面に全部表示したらどうなるか。
- ブラウザの読み込みに10秒以上かかる
- スクロールしても目当ての顧客が見つからない
- スマホで開くとさらに遅くなる
電話帳を思い浮かべてほしい。電話帳は「あ行」「か行」とページが分かれている。全ページを一度に開く人はいない。必要なページだけを開く。ページネーションは、これと同じ考え方をAPIに適用したものだ。
オフセット方式 — ページ番号で指定する
ページネーションの最も一般的な方法が「オフセット方式」だ。ページ番号と1ページあたりの件数を指定する。
GET /api/customers?page=1&limit=20
このリクエストは「1ページ目を、20件ずつ表示してほしい」という意味だ。
- page=1 → 1ページ目(1件目〜20件目)
- page=2 → 2ページ目(21件目〜40件目)
- page=3 → 3ページ目(41件目〜60件目)
レスポンス(サーバーからの返答)はこんな形になる。
{
"customers": [
{ "id": 1, "name": "株式会社田中商事", "industry": "製造業" },
{ "id": 2, "name": "山田デザイン事務所", "industry": "デザイン" },
{ "id": 3, "name": "鈴木法律事務所", "industry": "士業" }
],
"total": 3000,
"page": 1,
"limit": 20,
"total_pages": 150
}
total が全体の件数、total_pages が全ページ数だ。3,000件を20件ずつ分割すると150ページになる。
この情報があれば、画面に「1 / 150 ページ」と表示したり、「次のページ」「前のページ」ボタンを作ったりできる。
limit(1ページあたりの件数)は、画面の用途に合わせて変える。
- 一覧画面: 20〜50件が一般的
- ドロップダウンの選択肢: 100件程度
- CSVエクスポート: 1,000件以上
AIにアプリを作ってもらうときは、「一覧は20件ずつのページネーションで表示してほしい」と伝えるだけでよい。AIが page と limit のパラメータ処理を実装してくれる。
カーソル方式 — 「次はここから」で指定する
もう1つの方式が「カーソル方式」(カーソルベース・ページネーション)だ。ページ番号の代わりに、「次のデータの開始位置」を指定する。
GET /api/customers?cursor=abc123&limit=20
cursor=abc123 は、「前回の最後のデータの位置情報」だ。サーバーは「abc123の次から20件」を返す。
レスポンスはこんな形になる。
{
"customers": [
{ "id": 21, "name": "佐藤工務店", "industry": "建設" },
{ "id": 22, "name": "高橋会計事務所", "industry": "士業" }
],
"next_cursor": "def456",
"has_more": true
}
next_cursor が次のページを取得するための位置情報だ。「次のページ」ボタンを押すと、GET /api/customers?cursor=def456&limit=20 を送る。has_more が false になったら最後のページだ。
どちらが良いかはアプリの用途による。
管理画面や一覧表のように「3ページ目に直接飛びたい」場合は、オフセット方式が使いやすい。SNSのタイムラインのように「下にスクロールすると次のデータが読み込まれる」場合は、カーソル方式が向いている。
バイブコーディングでは、AIにどちらの方式を使うか指定できる。指定しなければ、AIはオフセット方式を採用することが多い。一般的な業務アプリであれば、オフセット方式で十分だ。
ページネーション付きの一覧画面をAIに依頼するテンプレート
実際にAIに依頼するときのテンプレートを紹介する。
テンプレート: ページネーション付き一覧画面
「顧客一覧画面にページネーションを追加してほしい。
条件:
- 1ページ20件表示
- ページ番号の切り替えボタンを画面下部に表示
- 現在のページ番号と総ページ数を表示(例: 3 / 150 ページ)
- 前のページ・次のページボタンも付ける
- APIは GET /api/customers?page=1&limit=20 の形式で
表示する項目: 会社名、業種、担当者名、最終連絡日」
このテンプレートのポイントは3つある。
1つ目: 1ページの件数を明示する。「20件」と具体的に書く。
2つ目: UIの要件も書く。「ページ番号の切り替えボタン」「前のページ・次のページ」など、画面にどう表示するかを伝える。
3つ目: APIのURL形式を指定する。page と limit のパラメータ名を明示することで、AIが独自のパラメータ名(offset, skip, per_page など)を使うのを防げる。
ソートとフィルタリング — ページネーションと組み合わせる
ページネーションは、ソート(並び替え)やフィルタリング(絞り込み)と組み合わせて使うことが多い。
たとえば、顧客一覧で「業種が製造業の顧客を、最終連絡日が新しい順に、20件ずつ表示する」場合、APIリクエストはこうなる。
GET /api/customers?industry=製造業&sort=last_contacted_at&order=desc&page=1&limit=20
分解すると:
- industry=製造業 → 業種で絞り込み
- sort=last_contacted_at → 最終連絡日で並び替え
- order=desc → 新しい順(降順)
- page=1&limit=20 → 1ページ目、20件ずつ
ここで注意点がある。絞り込みをすると total(総件数)が変わる。全顧客は3,000件でも、製造業だけに絞ると200件かもしれない。ページネーションの情報(total、total_pages)は、絞り込み後の件数に基づいて計算される。
AIに依頼するときは、「絞り込みとページネーションを両方使えるようにしてほしい」と一言添えるとよい。AIはフィルタリングとページネーションの組み合わせを正しく処理してくれる。
APIのバージョニング — 仕様変更で既存画面を壊さない仕組み
ここからは2つ目のテーマ、バージョニングだ。
アプリを使い続けていると、「この一覧にメールアドレスの列も追加したい」「レスポンスの形式を変えたい」「新しいフィールドが必要」といった要望が出てくる。APIの仕様を変更するということだ。
ここで問題が起きる。APIの仕様を変えると、その変更前のAPIを前提に作られている画面が壊れる可能性がある。
たとえば、顧客情報のAPIが name というフィールドを返していたとする。これを company_name に変更したら、name を参照している画面は全部エラーになる。
個人で使うアプリなら、全画面を一斉に修正すればよい。しかし、チームで使うアプリや、スマホアプリとWeb版が両方あるケースでは、一斉修正が難しい。スマホアプリはApp Storeの審査があるので、即座にアップデートできない。
そこで使うのがバージョニングだ。
バージョニングの基本 — URLにバージョン番号を付ける
最もシンプルなバージョニング方法は、APIのURLにバージョン番号を含めることだ。
- 旧バージョン: GET /api/v1/customers
- 新バージョン: GET /api/v2/customers
v1 と v2 で、返すデータの形式が違う。
v1のレスポンス(変更前):
{
"id": 1,
"name": "株式会社田中商事",
"phone": "03-1234-5678"
}
v2のレスポンス(変更後):
{
"id": 1,
"company_name": "株式会社田中商事",
"contact": {
"phone": "03-1234-5678",
"email": "info@tanaka-shoji.co.jp"
}
}
v2 では name が company_name に変わり、連絡先情報が contact というまとまりの中に整理されている。
v1 を使っている古い画面はそのまま動き続ける。新しい画面は v2 を使う。古い画面の改修が終わったら、v1 を廃止する。こうすれば、一斉修正しなくても安全にAPIを進化させられる。
バイブコーディングではバージョニングが必要になる場面は少ない
ここで正直に言うと、個人や少人数チームでバイブコーディングをしている場合、バージョニングが必要になる場面はほとんどない。
理由は3つある。
1つ目: バイブコーディングでは、AIがフロントエンド(画面側)とバックエンド(API側)を同時に修正してくれる。APIのフィールド名を変えるとき、画面側も一緒に修正するので、整合性が壊れにくい。
2つ目: 個人アプリやチーム内ツールであれば、利用者に「アプリを更新してください」と言えば済む。App Storeの審査を待つ必要がない。
3つ目: バイブコーディングで作るアプリは多くの場合Webアプリなので、デプロイ(公開)すれば全員が最新版を使う。古いバージョンを使い続ける人がいない。
ただし、以下のケースではバージョニングの知識が役に立つ。
- 外部のサービスやAPIと連携しているとき(相手のAPIがバージョンアップする可能性がある)
- スマホアプリ(iOS / Android)とWebアプリの両方があるとき
- 他社にAPIを公開しているとき
こうした場面に遭遇したら、「APIのバージョニングという仕組みがある」と思い出してほしい。AIに「APIにバージョニングを導入してほしい。/api/v1/ と /api/v2/ でURLを分けたい」と伝えれば、対応してくれる。
エラーレスポンスの設計 — エラーの中身を構造化する
ページネーションとバージョニングに加えて、もう1つ知っておくと便利な設計テクニックがある。エラーレスポンスの構造化だ。
第8回(ステータスコード)で、サーバーが 400 や 404、500 などのステータスコードを返すことを学んだ。しかし、ステータスコードだけでは情報が足りないことがある。
たとえば、新しい顧客を登録しようとして 400(Bad Request = リクエストに問題がある)が返ってきたとする。何が問題なのかが分からない。メールアドレスの形式が間違っているのか、必須項目が抜けているのか、会社名が長すぎるのか。
構造化されたエラーレスポンスは、この問題を解決する。
良くないエラーレスポンス:
{
"error": "Bad Request"
}
良いエラーレスポンス:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "入力内容に問題があります",
"details": [
{ "field": "email", "message": "メールアドレスの形式が正しくありません" },
{ "field": "company_name", "message": "会社名は必須です" }
]
}
}
良いエラーレスポンスは、どのフィールドに何の問題があるかを具体的に教えてくれる。この情報があれば、画面に「メールアドレスの形式が正しくありません」と表示できる。
AIにアプリを作ってもらうときは、次のように依頼するとよい。
テンプレート: エラーレスポンスの構造化
「APIのエラーレスポンスを構造化してほしい。
エラーが起きたとき、以下の形式で返すようにしたい:
- error.code: エラーの種類(VALIDATION_ERROR, NOT_FOUND, UNAUTHORIZED など)
- error.message: 人間が読めるエラーメッセージ(日本語)
- error.details: バリデーションエラーの場合、どのフィールドに問題があるかの配列
フォームのバリデーションエラーは、画面にフィールドごとのエラーメッセージを表示したい。」
3つのテクニックを組み合わせた実践例
ここまで学んだ3つのテクニック — ページネーション、バージョニング、エラーレスポンス — を組み合わせた、実践的な例を見てみよう。
あなたが20人のマーケティング会社の管理職だとする。顧客管理アプリをバイブコーディングで作り、半年ほど使ってきた。顧客データは800件に増え、いくつかの課題が出てきた。
課題1: 顧客一覧の表示が遅い(800件を一度に読み込んでいる) 課題2: 顧客登録時にエラーが出ても、何が間違っているか分からない 課題3: モバイル版を作りたいが、APIの形式を少し変えたい
これらをAIに一度に依頼するテンプレートはこうなる。
依頼例:
「顧客管理アプリに3つの改善をしたい。
改善1: ページネーション
- 顧客一覧を30件ずつのページネーションにする
- GET /api/customers?page=1&limit=30 の形式
- 画面下部にページ番号ボタン、前へ/次へボタンを表示
- 業種で絞り込んだときもページネーションが正しく動くようにする
改善2: エラーレスポンスの改善
- 顧客登録・更新のAPIで、バリデーションエラーが起きたときに:
- error.details にフィールドごとのエラーメッセージを含める
- 画面のフォームで、該当フィールドの下にエラーメッセージを表示する
- バリデーションルール: company_name は必須、email は形式チェック、phone は数字とハイフンのみ
改善3: API整理
- 将来のモバイル対応に備えて、APIのURLを /api/v1/customers の形式に統一する
- 既存の /api/customers は /api/v1/customers にリダイレクトする」
ポイントは、3つの改善を別々の依頼にするのではなく、1つの依頼にまとめていることだ。AIはこれらの変更が互いに影響し合うことを理解して、整合性のある実装をしてくれる。ただし、依頼が長くなりすぎると(10個以上の改善を一度に頼むなど)、AIが途中で忘れたり混乱したりすることがある。3〜5個の改善を1つの依頼にまとめるのが、ちょうどよいバランスだ。
よくある不安と答え
ページネーションを後から追加するのは大変か
比較的楽だ。バイブコーディングでは、AIに「顧客一覧にページネーションを追加して」と伝えるだけで、APIの修正と画面の修正を両方やってくれる。最初からページネーションを入れなくても、データが増えてきた段階で追加するのが一般的だ。目安として、一覧のデータが100件を超えたらページネーションの導入を検討するとよい。
1ページに何件表示するのが適切か
用途による。一般的な目安は以下の通りだ。
- デスクトップの管理画面: 20〜50件
- スマホの一覧: 10〜20件
- ダッシュボードのウィジェット: 5〜10件
迷ったら20件で始めて、使いながら調整するのが手堅い。
バージョニングのv1、v2は、アプリ全体のバージョンとは違うのか
違う。APIのバージョンは、APIの仕様(データの形式やフィールド名)のバージョンだ。アプリのバージョン(1.0、2.0など)とは別の概念だ。アプリのバージョンが2.0でも、APIはv1のままということがある。混同しやすいポイントなので覚えておくとよい。
エラーメッセージは日本語と英語のどちらで書くべきか
画面に表示するメッセージ(error.message や details 内のメッセージ)は日本語で書くのが自然だ。日本語のアプリで「Email is required」と表示されても、利用者には分かりにくい。一方、error.code(VALIDATION_ERROR、NOT_FOUND など)は英語の定型文にしておくほうが、プログラムで判定しやすい。AIに「エラーメッセージは日本語で、エラーコードは英語で」と伝えると、この使い分けを実装してくれる。
まとめ
データが増えたアプリを快適に使い続けるには、3つの設計テクニックが役に立つ。ページネーションは大量データを分割表示する仕組みで、一覧のデータが100件を超えたら導入を検討する。バージョニングはAPIの仕様変更で既存画面を壊さない仕組みで、個人アプリなら当面は不要だが概念を知っておくと安心だ。エラーレスポンスの構造化は、エラー時に「何が間違っているか」を具体的に返す仕組みで、フォーム画面の使い勝手を大きく改善する。いずれもバイブコーディングでは、AIに要件を伝えるだけで実装してもらえる。あなたの役割は、「いつ・何のために必要か」を判断して、AIに的確に依頼することだ。
次回は「JSON完全理解 — データ形式の文法とバリデーション」。第6回で触れたJSONをさらに深掘りし、複雑なデータ構造の読み方と、AIが生成したJSONの検証方法を学ぶ。
参考リファレンス
- 前回: 第13回「リソース設計の実践 — AIに伝わるデータ構造の考え方」(/articles/vc-013)
- 次回: 第15回「JSON完全理解 — データ形式の文法とバリデーション」(/articles/vc-015)
- バイブコーディング入門 カリキュラム(/vibe-coding)




