【ITニュース解説】When `@deprecated` cries wolf: Making Shopware’s next major upgrades easier
2026年08月25日に「Dev.to」が公開したITニュース「When `@deprecated` cries wolf: Making Shopware’s next major upgrades easier」について初心者にもわかりやすく解説しています。
ITニュース概要
Shopwareは、`@deprecated`タグがAPI廃止と将来の変更を混同し、警告が多すぎる問題を解決。今後は`@deprecated`をAPI廃止に限定し、互換性変更は専用属性で明確化する。これにより開発者は必要な対応に集中でき、バージョンアップ時の移行作業が効率的になる。
ITニュース解説
ソフトウェア開発の世界では、既存の機能を改良したり、より新しい技術に対応したりするために、コードに変更を加えることが頻繁にある。特に、プログラムの部品同士がどのように連携するかを定めたルールであるAPI(Application Programming Interface)が変更される場合、その情報がAPIを利用する開発者に正確に伝わることが極めて重要である。もし情報伝達がうまくいかなければ、ソフトウェアが予期せぬ動作をしたり、最悪の場合、動作しなくなったりする可能性がある。
これまでPHPのプログラムでは、@deprecatedという特別な目印(アノテーション)をコードに付けることで、そのAPIが将来的に廃止されるか、あるいは置き換えられるため、もう使うべきではないという意図を伝えてきた。開発ツールや静的解析ツールと呼ばれるプログラムは、この@deprecatedが付いているAPIが使われている箇所を見つけると、警告を出して開発者に注意を促す。これは、古いAPIに依存しているコードを事前に新しいAPIに移行させるための非常に有用な仕組みであった。
しかし、この@deprecatedの使い方が、一部で拡大解釈される問題が生じていた。特にShopwareというECサイト構築プラットフォームでは、APIが将来のメジャーバージョンアップで変更される際、その変更内容が実際には既存のコードの動作に影響を与えない場合であっても、計画段階で@deprecatedを付けて通知していたのだ。例えば、「このメソッドには将来的に新しいオプションの引数(パラメータ)が追加されます」といった変更は、現在の呼び出し方では問題なく動作し続ける。にもかかわらず、@deprecatedが付いているために、開発ツールはこれを「非推奨」として警告を発していた。
このような状況は、あたかも「狼が来た」と何度も嘘の叫びを上げる「狼少年」の話に似ている。本当に対応が必要なAPIの廃止や置き換えの警告も、そうでない警告も区別なく発せられるため、開発者は多くの警告の中から何が重要かを見極めるのが難しくなった。結果として、本当に対応が必要な@deprecatedの警告でさえ見過ごされたり、広範囲にわたる警告の抑制(無視する設定)が行われたりすることで、システムの健全な保守が阻害される事態に陥っていた。静的解析ツールは、@deprecatedという単純な信号しか受け取れないため、その中身に書かれたShopware独自の変更理由を正確に解釈することはできなかったのである。
この問題に対処するため、Shopwareは新しいアプローチを導入した。Shopware 6.7.14.0からは、@deprecatedの役割を本来の「APIが廃止または置き換えられるため、移行が必要」という明確な意味に限定したのだ。そして、それ以外の「後方互換性に関わる変更」(既存のコードの動作には影響しないが、将来的にAPIの振る舞いや構造が変わる可能性のある変更)については、専用のPHP属性という新しい仕組みを使って詳細に記述することにした。
これらの新しい属性は、Shopware\Core\Framework\Deprecation\BCChangeという特別な名前空間(コードを整理するための入れ物)にまとめられている。現在、型、パラメータ、可視性(アクセス範囲)、継承、例外契約といった様々な種類の変更に対応する約15種類の具体的な属性が提供されている。
さらに、これらの属性は、変更がどの開発者に影響を与えるかという観点から、大きく二つのカテゴリに分けられている。一つはCallSiteCompatibilityChangeで、これはAPIを「呼び出す」側のコードに影響を与える可能性のある変更を指す。もう一つはExtenderCompatibilityChangeで、これはAPIを「継承」したり、メソッドを「オーバーライド」したりするサブクラスのコードに影響を与える可能性のある変更を指す。例えば、メソッドの引数の型が将来的に狭まる(より具体的な型になる)変更は、現在その引数に将来の型に合わない値を渡している呼び出し側のコードに影響を与える。しかし、戻り値の型が狭まる変更は、呼び出し側には影響しないが、そのメソッドをオーバーライドしているサブクラスに影響を与える場合がある。
これらの属性には、NewOptionalParameter(新しいオプションの引数)、ReturnTypeNarrowing(戻り値の型を狭める)、ParameterNameChange(引数名の変更)など、変更内容を具体的に示す名前が付けられている。これにより、開発者は「このメソッドは非推奨です」という一般的な警告ではなく、「このメソッドにはv6.8.0で'states'という配列型のオプション引数が追加されます」といった、より具体的で構造化された情報を受け取れるようになった。
この新しい仕組みは、Shopwareの拡張機能開発者に多くのメリットをもたらす。まず、不要な@deprecated警告が大幅に減るため、静的解析ツールの出力が「ノイズ」の少ない、信頼性の高い情報になる。開発者は本当に対応が必要な警告に集中できるようになり、警告を無視する設定を減らすことができる。
さらに、新しい属性が提供する詳細な情報を用いることで、開発者は将来のメジャーバージョンアップに備えて、既存の拡張機能を前もって修正することが可能になる。例えば、Context::scope()メソッドに新しいオプション引数$statesが追加される場合、既存のコードはそのままでも動作するが、このメソッドをオーバーライドしているサブクラスは、Shopware 6.8がリリースされる前に、そのオプション引数を自分のメソッド宣言に追加しておくことができる。これにより、現在のShopwareバージョンとの互換性を保ちながら、将来のバージョンにも対応できる「前方互換性のある宣言」を今から行えるのだ。同様に、戻り値の型が変更される場合や、引数名が変更される場合も、事前に対応可能な修正を行うことで、メジャーバージョンアップ時の大規模な改修作業を回避し、より小さな段階的な変更として分散させることができる。
また、この構造化されたメタデータは、静的解析ツール(PHPStan)や自動リファクタリングツール(Rector)、IDE(統合開発環境)といった様々な開発ツールにとって非常に有用な入力情報となる。これらのツールは、属性の情報に基づいて、将来の非互換性につながるコードを自動的に特定したり、修正を提案したり、さらには自動で修正したりする機能を開発できるようになる。例えば、将来的に型が狭まる引数に対して、現在その型に合わない値を渡している呼び出し箇所を特定したり、引数名変更に対応していない名前付き引数を使っている箇所を検出したりといったことが可能になるだろう。
もちろん、すべての互換性問題を静的解析だけで解決できるわけではない。もし、メソッドが実行されたときに互換性のない古い使い方を検出できる場合は、Shopwareは引き続き「ランタイム非推奨警告」を発する。例えば、引数の型が?string(文字列またはnull)からstring(文字列のみ)に狭まる場合、もし呼び出し側がまだnullを渡しているなら、その実行時に警告を出すことで、本当に問題のある呼び出し箇所にピンポイントで警告を出すことができる。
開発者に求められる行動は明確である。まず、これまでの広範な@deprecated抑制設定を削除し、本当に必要な@deprecated警告に目を向けるべきである。次に、自分の拡張機能が利用しているShopware CoreのAPIにBC-change属性が付与されていないかを確認し、それが自分のコードに影響するかどうかを判断する。そして、もし影響があるならば、前述の例のように、現在のバージョンとの互換性を保ちつつ、将来のバージョンにも対応できるようなコード修正を、メジャーバージョンアップが来る前に積極的に行うべきである。
この新しいアプローチの目標は、「狼が来た」と偽りの叫びを上げる@deprecatedの状況を終わらせることである。これにより、@deprecatedの警告が出たら「行動が必要な廃止・置き換え」と信頼して対処し、BC-change属性が見つかったら「将来に備えるためのヒント」として活用し、バージョンアップをよりスムーズかつ安全に進めることが可能となる。Shopware 6.8はこのモデルから恩恵を受ける最初のメジャーアップグレードであり、今後もこの仕組みが活かされることで、開発プロセス全体の効率と安定性が向上することが期待される。