APIバージョニングの必要性
APIは時間とともに進化します。新機能の追加・バグ修正・セキュリティ向上のためにAPIを変更する必要がありますが、既存のAPIクライアントを壊さないことが重要です。適切なバージョニング戦略を選択して後方互換性を管理しましょう。
バージョニング戦略の比較
URLバージョニング(最も一般的)
// バージョンをURLに含める
GET /api/v1/users/123
GET /api/v2/users/123
// Express.jsでの実装
import v1Router from './routes/v1';
import v2Router from './routes/v2';
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
メリット:シンプル・可読性高・ルーティングが明確
デメリット:URLが変わるためクライアントの更新が必要
ヘッダーバージョニング
// リクエストヘッダーでバージョンを指定
Accept: application/vnd.myapi+json;version=2
// または独自ヘッダー
X-API-Version: 2
// Express.jsでの実装
app.use('/api/users', (req, res) => {
const version = req.headers['x-api-version'] || '1';
if (version === '2') {
return usersV2Handler(req, res);
}
return usersV1Handler(req, res);
});
クエリパラメータ(簡易的な方法)
GET /api/users/123?version=2
後方互換性を保つための原則
- フィールドの追加はOK:既存クライアントに影響しない
- フィールドの削除はNG:Breaking Changeになる
- デフォルト値を持つ新必須パラメータを追加する場合はOK(後方互換)
- 列挙型(enum)に値を追加する場合は注意:クライアントが unknown値を処理できるか確認
- ロバストネス原則:「寛容に受け取り、厳格に送る」
GraphQLのバージョニング
GraphQLは「バージョニング不要」を謳っていますが、それは設計の自由度が高いためです。実際には以下の方法で後方互換性を管理します。
type User {
id: ID!
name: String!
email: String!
fullName: String! # nameの代替として追加(後方互換)
# @deprecatedディレクティブで廃止予定フィールドを明示
username: String @deprecated(reason: "emailを使用してください")
}
APIの廃止(Deprecation)プロセス
// SunsetヘッダーでAPIの廃止予定日を通知
app.use('/api/v1', (req, res, next) => {
res.set('Sunset', 'Thu, 01 Jan 2027 00:00:00 GMT');
res.set('Deprecation', 'true');
res.set('Link', '</docs/migration/v2>; rel="deprecation"; type="text/html"');
next();
});
まとめ
APIバージョニングはAPIの長期的な品質と利用者との信頼関係を守るために不可欠です。パブリックAPIにはURLバージョニングが最もシンプルで扱いやすく推奨されます。破壊的変更はメジャーバージョンアップとして管理し、廃止予定バージョンには十分な移行期間(最低6ヶ月)を設けてください。