Vol.134(2023年4月22日発売)本連載では第一線のPerlハッカーが回替わりで執筆していきます。Webアプリケーションのリプレイス」です。Webアプリケーションをどう改善するか新規事業をPerlで開発する事例は減りましたが、Perlで開発されて現在も稼働中のサービスはあります。それらはクライアントとサーバが密結合したモノリスなWebアプリケーションの場合も多いでしょう。ために「クライアントとサーバを疎結合にしてAPI駆動な開発へリプレイスしたい」と考える方もいるはずです。リプレイスはほかのタスクと比較すると優先度が低くなりがちです。リプレイスは長い時間と人材や資金が必要だからです。リプレイスは、ユーザーのニーズよりも、サービスを運営する組織の課題解決を一時的に優先するとも言えます。ユーザーのニーズと利益を最優先に考えると、リプレイスの優先度は高くありません。一方で、技術の進歩と変化するユーザーのニーズに合わせてサービスが成長するために、リプレイスが必要になるのも事実です。Webアプリケーションのリプレイスで大事なことは2つです。Fowlerが提唱したStranglerパターン[1]を使うこと、もう一つは、便利なCPANモジュールを導入してモダンな書き方へ段階的に移行することです。浩二訳、オライリー・ジャパン、2020年、p.151)を参照してください。本稿ではまず、先人たちが提唱するリプレイスの方法から、リプレイスは、既存のコードを活用して段階的に進めながら、リプレイスの中断や再開も行えることが重要だと述べます。次に、Perlの後方互換性とStranglerパターンに着目して、既存のコードを活かしつつ新規のコードへ段階的に移行する方法を書きます。最後に、CPANモジュールを使ってモダンな書き方ができるAPIの実装を紹介します。先人たちの知恵を借りる本稿のリプレイスはStranglerパターンや『レガシーソフトウェア改善ガイド』[2]が紹介している「インクリメンタルな書き直し」を参考にしています。Webアプリケーションをどう改善できるかを説明します。クリス・バーチャル著、吉川邦夫訳『レガシーソフトウェア改善ガイド』翔泳社、2016年、p.133既存のコードは捨てずに、活かせるものは活かすみなさんのサービスが多くのユーザーに利用されているならば、既存のコードを捨てずに活かせるものは活かすのが賢明です。稼働中のコードは多くのユーザーに利用され、テストされ、多くのバグが修正されているからです[3]。I」を参照してください。Kit)のサポートも手厚い言語へ変更したくなります。開発言語の変更はリプレイスではなくリライトになり、既存のしくみやコードを活かすのが難しくなります。既存のコードを別の開発言語へ書き換えないと解決できない課題がない限り、既存のコードはできるだけ活かすことを考えるべきです。既存のコードを活かすなら、Perlの後方互換性は有用です。5の後方互換性は比較的よく保たれており、コードをあまり書き換えずにPerlのバージョンアップやモダンなCPANモジュールを利用できます。この後方互換性を利用すれば、既存のコードを捨てずに活かせるものは活かす選択をとれます。リプレイスは段階的に進めて、中断したり再開してもよい稼働中のサービスをリプレイスするなら、仕様変更は最小限にとどめます。変更範囲を絞り、機能単位で段階的にリプレイスを進めます。これらはリプレイスの技術的なハードルを下げ、失敗のリスクをできるだけ小さくするために重要です。画面のURLパスをロードバランサのルーティングで判定して、向きを移行先のアプリケーションへ段階的に切り替える方法があります[4]。機能が少なく影響範囲も画面単位で閉じるものを対象にするとよいです。Applications」を参照してください。リプレイスは中断や再開ができる状態にすべきです。リプレイスのみに開発チームの全リソースを当てられる組織はまれです。多くの場合、ユーザーからの要望や売上を改善するタスクが優先されます。中断や再開ができれば、優先されるタスクが片付いたあとにリプレイスを再開できます。失敗する可能性を考慮してロールバックも可能にすべきです。リプレイスしたコードをもとに戻せる状態を一定期間は保ちましょう。これらの対策は長いリプレイスを安全に進めるために必ず検討すべきです[5]。HTTPレスポンスのステータスコードを302、303、307の一時的なリダイレクトにしたり、Cache-Controlをno-storeにしたりするなどの対策があります。これらはロールバック時にブラウザなどに状態がキャッシュされ、リプレイス前の状態に切り替わらない事態への対策です。FowlerのStranglerパターンです。このパターンは、新しいサービスを導入しながら既存のシステムを包みつつ、外側から内側に向けて新しいシステムへと段階的に置き換えるアプローチをとります。Stranglerとは着生のつる植物のことです。つるは高木の周囲に癒着して最終的に木を絞め殺すことから、新しいコードをつる植物に、既存のシステムを木になぞらえて名付けられました。このパターンの初期段階では、既存のコードが新しいシステムの上で安定稼働する状態を目指します。既存のコードを新しいコードで包めば、既存のコードを変更せずに影響範囲を限定できます。これで、リプレイスの初期コストと変更で発生するリスクの低下が見込めます。変更範囲が小さいため、早期のデプロイやリリースが可能となり、本番稼働で明らかになる課題やユーザーからのフィードバックを早期に受け取れます。このサイクルを長期的に回しながら、新しいコードで既存のコードの課題を解決していきます。既存のコードをモダンなアーキテクチャで包む前節では、先人たちの手法の共通点からリプレイスの心得を学びました。WebアプリケーションをAPI駆動な開発へリプレイスする設計を説明します。APIサーバを中心にサンプルコードを使って説明します。サンプルコードはGitHubに公開しています。利用するPerlのバージョンは5.36.0です。各種CPANモジュールのバージョンは執筆時点での最新版を利用しています。詳細は、サンプルコードのcpanfileを参照してください。既存のコードと新規のコードをlibで分割する今回は説明を簡略化して、既存のコードはデータベースを直接参照するコードのみにします。既存のサービスからそのままコードを切り出します。移行前がMonolithで移行後をAPIとした場合、ディレクトリ構成は以下になります。APIを実装しています。そのテストコードをt/controller/tester.tに配置しています。<続きの(2)はこちら。Ltd.ページ内容の全部あるいは一部を無断で利用することを禁止します⁠。個別にライセンスが設定されている記事等はそのライセンスに従います。