すべての「コア」ビジネスデータを一元化する内部REST APIからのデータを消費するWebアプリケーションを構築することを計画しています。デモンストレーションの問題として、このAPIがデータを公開するとします。非常に大規模なProductsデータベース。したがって、APIを使用するWebアプリケーションの例は次のようになります。
すべての製品を一覧表示するビュー。ユーザーは「ウィッシュリスト」に製品を追加できます。 (非常にばかげた例)
ここでの難しさは、ユーザー製品について知る必要があるたびに、製品名やその他のデータを取得するためにAPIにリクエストを送信する必要があることです。これは、そのIDを内部に保存するだけだからです。これはこの単純な例では問題ありませんが、これよりもはるかに複雑なケース(レポートなど)があり、常にAPIからデータをフェッチするのは非常に間違っているようです。そこで、いくつかのアプローチを考え出しました。
1-レコードを作成し、データベースに内部的に保存するビューでAPIから製品をフェッチします。製品を使用する他の領域は、APIからではなく、データベースからクエリします。
2-ある種のキャッシング戦略。しかしここで?キャッシングの責任者は誰ですか? APIまたはクライアント?もしそうなら、どの戦略がこのケースに適していますか?
ケース1もっともらしいソリューションのように聞こえますが、同期の問題が発生します。変更が加えられたかどうか(名前など)を頻繁に確認する必要があります。
ケース2良いもののように聞こえますが、私は個人的にこれまで同様のアーキテクチャを見たことがなく、実装したこともありません。
もう1つ思いついたのは、IDをローカルデータベースに保存するだけの場合、すべてのデータを使用してビューを「構築」する必要がある場合、ユーザー製品のすべてのIDを取得するローカルデータベースにクエリを実行する必要があるということです。 APIにリクエストを送信して製品を取得します。問題? APIは、ユーザー->製品間の関係を認識していないため、すべての製品にクエリを実行し、何らかの方法でデータをマージする必要があります。
どんな種類のアドバイス、共有された経験、または基本的にどんな入力でも大歓迎です。
PS1: APIとWebアプリはどちらもC#で記述されています。
PS2:質問で「内部API」と言ったとき、それは私たちのチームが設計したAPIであることを意味していました。タイトルの外部は、APIがWebアプリから分離され、外部リソースのように機能することを意味します。
私が正しくフォローしている場合は、データにダムインターフェイスのみを提供するAPIの使用を検討しています。つまり、APIを介してクエリを実行することはできず、一度にすべてのデータを要求することしかできません。
したがって、1人のユーザーの製品を検索する場合は、すべてをフェッチする必要があります。たとえば、2,000万個の製品を取得し、クライアント側でユーザーに属する製品をフィルタリングして、それらのみを表示します。
そうだとしたら、うんそれは吸うでしょう。
最善の解決策は、APIチームにAPIを変更するように依頼することです。これにより、APIを照会できるため、すべてまたはまったくではなく、特定のリソースを要求できます。
それが不可能な場合は、API呼び出しの前にキャッシュを配置して、少なくとも高速になるようにしてください。
それができない場合は、もう1つの方法として、memcacheのようなものを使用して、データの各ダンプを保存します。このキャッシュを無効にするタイミングを制御できます(たとえば、毎分程度)。
最終的には、データAPIが解決できない場合は、思いついたソリューションに苦労することになります。そのため、そのチームにAPIを改善するように働きかけることができれば
RESTエンドポイントを提供するWebサービスが存在するサーバーの負荷を軽減したい場合、これらのサーバーにキャッシュを導入する以外に方法はありません。
クライアントがアプリケーションにキャッシュを導入する必要があるという制約を指定して、クライアントがサービスに頻繁にアクセスしないようにすることもできますが、クライアントが同じ会社である場合でも、実際にそれが発生することをどのように保証しますか。
確実に実行したい場合は、独自のシステムに導入してください。他の人が重い仕事をすることを期待しないでください。
ちなみに、Webサービスの背後でデータベースをカプセル化する目的は、リクエストをインターセプトするミドルウェアを導入することです。リクエストは、データベースに送られますが、RedisやElasticなどのシステムにも転送できます。
クライアントがAPIを呼び出してデータAを取得した後、値Aに基づいてデータベースを手動でクエリする必要がある場合、中間層はほとんど意味がありません。
すべてがそれを通過する必要があります。
一方、Webサービスが安定していて高速で、応答が迅速に提供され、クライアントがapiの呼び出しがアプリケーションのボトルネックであると感じている場合は、アプリケーションを高速化するのはクライアントの責任であり、アプリケーションを高速化するのはクライアントの責任です。
1日の間に実行できるリクエストの量によって制限されない限り、データを取得するためにWebサービスをヒットすることはすべて悪いとは見なされません。
複雑すぎないこと。
Webサービスからの応答が速くなると思いますか? Webサービス要求を消費するシステムにキャッシュを導入します。
Webサービスからの応答は十分に高速ですが、クライアントアプリケーションは常にWebサービスを呼び出す必要があるため、まだ遅いですか?クライアントアプリにキャッシュを導入します。
あなたが言った:
ここでの難しさは、ユーザー製品について知る必要があるたびに、製品名やその他のデータを取得するためにAPIにリクエストを送信する必要があることです。これは、そのIDを内部に保存するだけだからです。この単純な例ではこれで問題ありませんが、これよりもはるかに複雑な場合(たとえば、レポート)があり、APIから常にデータをフェッチするのは非常に間違っているようです。
少なくとも最初は、APIから常にデータをフェッチするのは間違っていますis間違っています。あなたはキャッシングについて話しているが、キャッシングを導入するとすぐに、そのキャッシュについて無効化と更新について心配する必要があり、それは常に大きな問題です。
では、少し前に戻って、パフォーマンスの問題が発生することを知っていますか?信頼性の高いキャッシュを導入することの複雑さを考えると、おそらくソリューションを立ち上げて実行し、パフォーマンスの向上を導入する前にボトルネックがどこにあるかを判断します。