APIの変更

開発者を失わずにAPIを非推奨化する方法

1分で読めます

APIを非推奨化するということは、あるものが今日はまだ動作しているが、宣言された日付までに動作しなくなると告知し、その約束の両方の半分を守ることを意味する。多くの非推奨化は後半の半分で失敗する。日付が静かにずれるか、それが到来して、通知を一度も見たことのない呼び出し元がエラーからそれを知ることになる。非推奨化が完了するのは、影響を受けたすべての呼び出し元が移行したか、あるいは個別にまだ移行していないと伝えられたときだ。

APIの非推奨化とは何か

非推奨化とは、エンドポイント、フィールド、バージョンがなくなると告知することと、それを実際に削除することの間の期間だ。その期間中、古い動作は動作し続け、ドキュメントはそれがなくなると述べ、すべての応答は機械可読な警告を運ぶ。削除は別の、より後の出来事であり、しばしばサンセットと呼ばれる。この二つは混同され、まさにその混同が害を生む場所だ。「deprecated」は「もうすでになくなっているかもしれない」を意味し始め、呼び出し元はどちらの言葉も信頼しなくなる。

用語意味呼び出し元が頼れるもの
Deprecatedなくなると告知され、まだ動作しているサンセット日までの完全な動作
Sunset動作しなくなる日付この日付以降は何もない
Retired / 削除済みなくなった。リクエストは失敗するエラー、理想的には代替を名指しするもの
Legacy未定義。この言葉は避けよう何もない。それこそが問題だ

非推奨化の期間はどのくらいであるべきか

呼び出し元がそれを知り、作業をこなすのに十分な長さで、あなたがそれを書いた時点からではなく、通知が実際に届いた時点から測る。90日は公開ウェブAPIの一般的な下限だ。12か月は、エンドユーザーがインストールするソフトウェアに組み込まれたものには普通だ。修正が彼らのリリースプロセスも通過しなければならないからだ。GoogleのバージョニングガイダンスであるAIP-185は、妥当な移行期間を求め、ベータ機能を削除する場合でも180日を推奨しており、Kubernetesは自らの非推奨化ポリシーを月数ではなくリリース数で文書化している。それは呼び出し元がバージョンごとにアップデートする場合に正しい単位だ。

期間を選び、それをポリシーとして書き留め、変更ごとにそれを決め直すのをやめよう。公開されたポリシーは、すべての非推奨化を交渉からルールの適用へと変える。

非推奨化ポリシーを書き留めることはウィンドウの開始をカバーする。APIバージョンの終了 は、期間が実際に尽きてバージョンが動作を停止したときに最後に必要となる、別の通知を扱っている。

非推奨化のスケジュール

初日にまとめて告知される四つの日付。それぞれが到来したときに個別のチェンジログ項目になるため、チェンジログだけを読む人にはその物語が四回語られることになる。

  1. 告知する。 項目は何が非推奨化されるか、なぜか、それが何に置き換わるか、そしてサンセット日を述べる。古いものについてのドキュメントは、移行先へのリンクを持つバナーを得る。応答は下に説明されるヘッダーを得る。
  2. 半分の時点でリマインドする。 二つ目の項目、そして古い動作をまだ使っているすべての呼び出し元への直接のメッセージ。これは利用データを必要とするステップだ。非推奨化されたエンドポイントをまだ呼んでいるのが誰かをリストできないなら、これはできない。それは次の非推奨化までに解決する価値がある。
  3. 日付の少し前にブラウンアウトする。 短い期間、一時間または一日、古い動作にエラーを返し、それから復元する。すべての通知を見逃した呼び出し元は、まだ時間があるうちにそれを今知ることになる。GitHubは、APIのパスワード認証を廃止する前に、計画されたブラウンアウトを使った。このリストの中で最も効果的な単一のステップだ。
  4. サンセット。 それを削除する。それを置き換えるエラーは、代替先を名指しし、移行ガイドにリンクする。エラーを長く維持しよう。404は呼び出し元に何も伝えない。

非推奨化の通知は何を述べるべきか

非推奨化の通知は、何がなくなるか、いつ止まるか、代わりに何を使うか、そして誰に影響するかを述べる。以下はその形式を埋めたものだ。

GET /v1/reports/dailyは非推奨化されており、2027年3月1日に動作しなくなります。 GET /v2/reports?granularity=dayに置き換えられ、安定したスキーマとページネーションで同じデータを返します。過去30日間にv1エンドポイントを呼び出した214の連携に影響します。もしあなたのものがその一つなら、この通知はメールでも届きます。移行ガイド:[リンク]。2027年3月1日までは何も変わりません。その日付以降、v1エンドポイントはこの項目へのリンク付きで410 Goneを返します。

すべての文が、読者が必要とする何かを運んでいる。影響を受けた連携の数は、それぞれの読者に読み続けるべきかを伝える。「まで何も変わりません」は、影響を受けない人にタブを閉じさせる文だ。チェンジログの例のページは、この形式を一貫して書いているチームの項目を集めており、自分の最初のものを書く前に三つ読む価値がある。

非推奨化されたエンドポイントはどんなヘッダーを送るべきか

告知の日から、非推奨化されたエンドポイントからのすべての応答で、後継へのDeprecation、Sunset、Linkを送ろう。Deprecationヘッダーは非推奨化が発効した日付を運び、Sunsetヘッダーはエンドポイントが応答しなくなる日付を運び、Link: <url>; rel="successor-version"は代わりに何を使うべきかを示す。

HTTP/1.1 200 OK
Deprecation: @1756425600
Sunset: Mon, 01 Mar 2027 00:00:00 GMT
Link: <https://api.example.com/v2/reports>; rel="successor-version"
Link: <https://example.com/changelog/daily-reports>; rel="deprecation"

多くの呼び出し元は、ヘッダー自体を読むことは決してないだろう。その価値は、呼び出し元のHTTPクライアント、ゲートウェイ、モニタリングがそれを読めることにあり、それがあなたの非推奨化を、あなたの側のページではなく彼らの側のアラートに変える。あなたが出荷するSDKは、それを見たときに警告をログに出すべきだ。

誰に知らされたか、そしてそれをどう知るか

これは、サンセットが静かに終わるか、サポートのインシデントになるかを決めるステップであり、チェンジログだけで行うのが最も難しいものだ。チェンジログの項目は、チェンジログを読むすべての人に知らせる。非推奨化は、コードが失敗する具体的な人々に届く必要があり、彼らを見つける通常の方法は、半分の時点でのリマインドが必要とするのと同じ利用データだ。最近非推奨化された動作を呼び出したAPIキー、アプリ、アカウントだ。

私たちが実行しているループ。項目は非推奨化を追加するpull requestから作成され、人間が言い回しと日付をレビューし、公開されると項目自体が通知になる。その問題についての、あるいは代替を求めるウィジェットのフィードバックが、pull requestがクローズするGitHub issueになった人は誰でも、それが出荷されたことを伝える項目へのリンク付きのコメントをそのissueで受け取る。フィードとウィジェットは同じ項目を他のすべての人に提供する。それはAPIチェンジログにある他のすべての項目と同様だ。私たちがしないことは、人間がそれを公開する前に非推奨化が「出荷された」ことにすることだ。間違った日付の通知は、通知がないよりも悪い。

あなたのツールが何であれ、サンセットの日に答えられなければならない問いは、先週まだこれを使っていたのはどの呼び出し元で、そのうちどれに直接伝えたか、というものだ。答えが「それについて投稿した」であれば、サンセットはまだ準備ができていない。

非推奨化とバージョニングの違いは何か

バージョニングは、新しいものが存在する間、古い動作を利用可能に保つ方法だ。非推奨化は、古いものを引退させる方法だ。以前のバージョンのための非推奨化ポリシーのない新しいAPIバージョンは、両方を永遠に運用する約束にすぎない。バージョニングのない非推奨化は、遅延を伴った破壊的変更だ。両方が必要であり、バージョンは簡単な方の半分だ。GraphQLは名指しする価値のある例外だ。通常そこにはそもそも上げるべきバージョン番号が存在せず、GraphQLスキーマの非推奨化は、一つの共有されたスキーマが代わりにディレクティブでフィールドを引退させる方法を扱っている。

FAQ

非推奨化されたエンドポイントは以前とまったく同じように動作し続けるべきか? サンセット日まではそうだ。許される変更は、追加されたヘッダーと、終わりに近い時期に事前に告知された計画的なブラウンアウトだけだ。

引退したエンドポイントはどんなステータスコードを返すべきか? 410 Gone。代替とチェンジログの項目を指すLinkヘッダー付きの本文とともに。404はそのURLが一度も存在しなかったと述べており、それは間違っていて役に立たない。

非推奨化の期間を短縮できるか? セキュリティ上の理由でのみ。古い動作が悪用可能であれば、そう述べ、期間を短縮し、チェンジログに頼るのではなく、影響を受けたすべての呼び出し元に直接伝えよう。

フィールドを非推奨化する必要があるのか、それともエンドポイント全体だけか? フィールド、パラメータ、enumの値、デフォルト値、ヘッダーはすべて同じ扱いを必要とする。それぞれが正しい呼び出し元を壊しうるからだ。削除されたフィールドは最も一般的な非推奨化であり、最もよく見過ごされるものでもある。


この記事の技術的な記述は第三者による確認を受けていません。誤りがあればお知らせください。修正します。

changeloopの関連ページ: 開発者向けドキュメント, changelogの例

changeloop
ループを閉じるchangelogを作っているチームです。ユーザーが何かを求め、あなたのチームがそれを届け、求めた人がそれを知る。