過去には、開発者 (もちろん私自身も含む) があらゆるケースで読み取りと書き込みの両方に同じ API を使用するという一般的なアプローチがよく見られました。さらに、両方の操作を処理するために、MySQL/PostgreSQL などの同じデータ ソースに依存することもよくありました。
これは、同じ列に書き込み、そこから読み取ることを意味します。そのため、頻繁にクエリされるフィールドのインデックスを最適化する際に問題が発生することがよくあります。
たとえば、新しいフィルターに対応したり、クエリのパフォーマンスを向上させるためにインデックスを頻繁に調整する必要があり、LIKE などの演算子で使用されるフィールドはパフォーマンスに影響を与えるため、特に課題がありました。
これらの変更により、更新された機能を公開するための API の変更、追加の JOIN による測定時間など、バックエンドのさらなる調整が必要になることがよくあります。
API に新しいフィルターなどを追加するという課題に対処するために、 ApicalypseやもちろんGraphQLなどのツールや標準を使用してプロセスを最適化する試みがありました。
これらのソリューションは、API クエリ生成を合理化し、新しいフィルターや機能を実装するために必要な手作業を削減し、データ アクセスを処理するためのより動的なアプローチを提供することを目的としていましたが、学習曲線が急でした。
CQRS (コマンド クエリ責務分離) の台頭により、新しいアプローチが登場し始めました。この考え方により、書き込みと読み取りに別々のソースを使用することが推奨されました。書き込みではイベントを発行でき、読み取りでは専用の場所でそれらのイベントからビューを構築できます。読み取りと書き込みが同じデータベース (ただし異なるテーブル) 内で管理されていたとしても、この分離によって大きなメリットがもたらされ、もちろん、2 番目の課題であるドメイン モデルでの JOIN と検索クエリも解消されました。読み取りモデルは一般に非正規化された JSON 形式であるためです。
しかし、これによって別の問題が発生しました。読み取りでは書き込みをスケールする必要があり、アプリケーションのインスタンスを X から Y にスケールする必要があった唯一の理由は読み取りのためでした。この問題はキャッシュによって部分的に軽減でき、マイクロサービスの世界では読み取り専用のマイクロサービスを用意できます。
しかし...
それでも、これはモジュラーモノリスなどの他のアーキテクチャスタイルにとっては理想的なソリューションではありませんでした。そのような分離はシステムの設計哲学とうまく一致しない可能性があります。また、API がダウンすると製品全体がダウンし、ほとんどの製品が書き込みよりも読み取りに依存していることを考慮すると、ビジネスに不必要な影響を与える可能性があります (もちろん、API がダウンすることとは別です ;) )
では、API を介さずに、読み込み処理を行わずに、これらの「ビュー」(読み取りモデルとも呼ばれる) を直接要求できるとしたらどうなるでしょうか。ここで、 Meilisearch 、 AppSearchなどのソリューションが役立ち、「Valet Key」と呼ばれるパターンを活用します。このパターンを使用すると、フロントエンドは読み取り最適化モデルに直接アクセスできるため、バックエンド API への依存が軽減されます。もちろん、フロントエンドは引き続き API に「Valet Key」を「要求」する必要がありますが、フロントエンドはキーをキャッシュできるため、API がダウンしている場合でも、フロントエンドは通信してコンテンツを表示できます。
このアプローチにより、読み取りデータベースに集中でき、API での読み取りトラフィックの処理について心配する必要がなくなります。API 経由でフロントエンドに提供される「Valet Key」は、フロントエンドが変更できない方法で保護されます。これには、定義済みのフィルターとインデックスが含まれます。
フロントエンドに追加機能が必要な場合は、API を通じてそれらをリクエストできます。API はそれらを許可するかどうかを検証できます。それでも呼び出し回数は少なくなります。
私が見つけた利点は次のとおりです:
しかし、欠点も常に存在します。
したがって、このアプローチは万能薬ではなく、独自の課題をもたらしますが、欠点を受け入れられるのであれば、フロントエンドの小さな変更にはバックエンド チームの関与は必要なくなり、開発プロセスが合理化され、全体的な俊敏性が向上し、もちろんスケーラビリティも容易になるはずです。