2023年2月23日(木) ·5分で読めます

最後の破壊的変更

安定した仕様に向けて進むにつれて、JSONスキーマのさまざまなコンポーネント、動作、および機能を分析し、何を含めることができるか、何を変更する必要があるか、そして(もしあれば)削除または置き換える必要があるかを判断してきました。私たちが抱えていた主な疑問は、既存のスキーマを使用しているユーザーに問題を引き起こすような変更、つまり破壊的な変更が計画されているかどうかでした。

それに答えるために、ユーザーの意見が必要でした。そこで、今後のリリースでの破壊的変更の扱い方に関するGitHubでの特定の会話への参加を促すために、インターネット全体に投稿しました。その反応は、「できることなら、壊さないでほしい」というものが非常に多くありました。しかし、多くの人が、明確な移行パスとそれを支援するツールがあれば、それほど困らないだろうとも述べていました。

また、JSONスキーマのコアチームメンバー全員が参加する、機能の安定性に関する内部調査も実施しました。その結果、Draft 2020-12の大部分は完全にそのまま維持できることをご報告いたします。いくつかのキーワードと動作には微調整が必要ですが、ほとんどの場合、現在のリリースとの互換性があると感じています。

ユーザーとチームメンバーの両方の間で共通していたもう1つの感情は、JSONスキーマにはすでに、仕様の新しいバージョンをリリースするときに破壊的な変更を含めるという歴史(と評判)があるということでした。つまり、あるバージョンで適切に検証されたスキーマが、次のバージョンでは適切に検証されない可能性があるということです。この認識は、私たちが対処する必要があるものです。そのためには、あるバージョンで記述されたスキーマが、その後のすべてのバージョンで一貫して検証されることを約束できるように、私たち自身と仕様の方向性を定める必要があります

残念ながら、その約束を守るためには、未知のキーワードのサポートという、どうしても破壊的な方法で変更しなければならない動作が1つあります。

未知のキーワードとは?

キーワードは、スキーマのメタスキーマ($schemaの値で識別されます)にリストされている語彙によって定義されている場合に「既知」となります。この語彙を認識し、スキーマの処理を続けることで、実装は、その語彙が定義するすべてのキーワードの処理方法を理解していることを宣言します。スキーマのメタスキーマにリストされている語彙によって定義されていないキーワードはすべて「未知」と見なされます。

現在公開されているすべてのバージョンのJSONスキーマでは、実装に対して(少なくとも)認識されないキーワードを無視するように指示しています。Draft 2019-09でアノテーションが導入されたことで、実装は未知のキーワードの値を収集し、出力でユーザーに報告するオプションが与えられました。この動作は、検証に影響を与える心配をせずにスキーマにアノテーションを付けたり、文書化したりできることを意味したため、コミュニティで広くサポートされました。次のようなスキーマの場合、

スキーマ
{ "$schema": "https://json-schema.dokyumento.jp/draft/2020-12/schema", "type": "object", "properties": { "firstName": { "type": "string", "database-field-id": 1234 } }}

バリデーターは、database-field-idを無視するか、それとその値をアノテーションとして出力に含めるかのいずれかを行います。この機能がいかに役立つかが見て取れるでしょう。ただし、この機能は、将来の互換性を約束する能力も妨げます。

なぜ、今でもこれをサポートできないのでしょうか?

あるユーザーが、2023年版の仕様に準拠して作成されたバリデーターを使用している間に、上記のスキーマ例を作成したと仮定します。数年後、そのユーザーは2025年版の仕様をサポートするようになったバリデーターにアップグレードしたいと考えています。しかし、その2025年版の仕様では、database-field-id がキーワードとして追加され、その値は文字列であることが期待されています。すると、突然ユーザーのスキーマは無効になってしまいます。新しいキーワードを追加したことで、ユーザーを壊してしまったのです。

このシナリオを防ぐために、リストされた語彙によって宣言されていないキーワードを禁止せざるを得ません。これが多くの人に最初から影響を与えることを認識しています。しかし、将来の互換性のある仕様の約束は、スキーマをまた変更しなければならない(そして将来的には永遠に変更しなければならない可能性がある)という当面の苦痛よりも優先されるべきだと感じています。

その影響を和らげるために何がされていますか?

このまさにこのトピックについて、オープンな議論を行っており、皆様からのご意見をお待ちしております。

現在の提案には、カスタムアノテーションを示すための未知のキーワードへの単純なプレフィックスから、titlereadOnly のようにアノテーション専用のキーワードを定義できる、スキーマにバンドルされたインラインおよびアドホックな語彙のようなより複雑なソリューションまでが含まれています。これらのオプションは、事実上、スキーマ作成者が「これらのキーワードがどの語彙にも宣言されていないことは知っていますが、どうしてもスキーマに含めたいのです。無視してください」と言うための方法です。

次のリリースで他に破壊的な変更はありますか?

おそらくないでしょう。未知のキーワードのサポートを削除することが、実質的に唯一の悪影響のある変更であると考えていますが、それほど重大ではない形で物を壊す可能性のある他の変更の可能性を排除するものではありません。

このような破壊的な変更を行うことは、ユーザーと実装者の両方の開発者にとって困難であることを認識しており、必要な変更を測定し、可能な限り破壊的な変更の代替案を模索するために最善を尽くしています。これは、変更を好き勝手に行う機会とは考えていません。

いずれにせよ、私たちは、破壊的な変更であろうとなかろうと、行った変更についてはオープンかつ透明性を保ちます。

まとめ

次のバージョンで一部のスキーマを壊す必要があるようです。しかし、そうすることで、将来は壊さないと約束できるようになります。

直すためには壊す必要があります。

カバー写真:Ken SuarezUnsplashより)