Kentico Cloudコンテンツをアプリのキャッシュに保存していますか?最新のエントリだけで、キャッシュをすっきりさせたいと思ったことはありませんか?このハウツー記事では、KenticoCloudからのWebhook呼び出し時に廃止されたキャッシュエントリをクリアする方法を示します。
ステップバイステップの方法で、Kentico CloudでWebhookを構成し、Webhook呼び出しをリッスンしてキャッシュエントリを適切にクリアする単純なASP.NET CoreMVCアプリを作成します。
一般に、KenticoCloudを利用するアプリは多くのキャッシュを必要としません。 Kentico Cloud Delivery / Preview APIサービスは、ミリ秒単位で測定される応答待ち時間で、世界中で運用されているCDNネットワークを介してコンテンツを公開します。したがって、Webアプリは必ずしもコンテンツをキャッシュする必要はなく、KenticoCloudを直接参照できます。
ただし、キャッシュを実装する理由がある場合があります。KenticoCloudに対して行われたAPIリクエストを節約したい場合があります。無料プランには月額50,000のAPIリクエストが含まれ、有料プランにはさらに多くのプリペイドリクエストが含まれるため、コンテンツをキャッシュする必要はありませんが、キャッシュしたい場合は、次のように設定します。キャッシュを最新の状態に保つためのwebhook。
問題
つまり、KenticoCloudコンテンツアイテムを一定期間キャッシュするアプリがあります。しかし、キャッシュエントリの有効期限が切れる前に、コンテンツ寄稿者がKentico Cloudのコンテンツアイテムを変更するとどうなりますか?アプリは、コンテンツアイテムの廃止バージョンを提供します。これが起こりたくないことであると想定して、Webhook機能を設計しました。キャッシュを無効にするだけではありません。 webhookは、アプリがKenticoCloudで発生するイベントのシグナルを取得したい他のさまざまなケースに対応します。例については、KenticoテクニカルエバンジェリストのBryanSoltisによるWebhookを使用したAzureSearchインデックスの更新に関する記事を参照してください。
ソリューション
Webhookは、KenticoCloudがアプリの事前構成されたパブリックにルーティング可能なURLアドレスに送信するHTTPPOSTリクエストに他なりません。 Webhookリクエストのコンテンツ(つまりペイロード)には、何が起こったかに関する詳細情報が常に含まれています。このようにして、アプリは適切に反応できます。たとえば、廃止されたキャッシュアイテムをクリアします。
Kenticoクラウドをセットアップする
上で宣伝したように、私が最初にセットアップした場所はKenticoCloudでした。ここでは、メインメニューに移動して「Webhooks」を選択しました。このメニュー項目には、「開発者」および「プロジェクトマネージャー」の役割からアクセスできます。
その後、手順は非常に簡単でした。
[新しいWebhookを作成]をクリックすると、簡単なダイアログが表示されました。
名前として「CacheWebhook」と入力し、将来のアプリのWebhookエンドポイントのパブリックURL(「http://example.com/webhook」)を入力しました。次に、生成されたシークレットを書き留めたら、アプリを作成する準備が整いました。
サンプルアプリを作成する
この部分が複雑になると予想した場合は、今すぐがっかりさせます。かなり簡単です。
以前と同様に、「DotnetNew」コマンドを使用してボイラープレートコードテンプレートをデプロイしました。
最高レベルの観点から、次の手順でロジックを実装しました。
- 私はと呼ばれるクラス作成のCacheManagerの状態を管理する責任あるMemoryCacheを。
- 既存のCachedDeliveryClientクラスのコードを少し変更して、新しく作成されたキャッシュアイテムとその依存関係の識別子(コードネーム)を準備するだけにしました。次に、CacheManagerクラスを呼び出してキャッシュを操作します。
- 私はと呼ばれる新しいMVCコントローラ添加WebhookController上記ウェブフックエンドポイントを表すようにします。コントローラはCacheManagerを呼び出して、キャッシュエントリを無効にします。
CacheManagerクラス
MemoryCacheオブジェクトへの参照を保持する以外に、このシングルトンクラスには、GetOrCreateAsync とInvalidateEntryの2つの重要なメソッドがあります。
最初のメソッドは、CachedDeliveryClientのGetItem(s)Asyncメソッドによって呼び出されます。このメソッドは、「identifierTokens」、「valueFactory」、および「dependencyListFactory」を入力パラメーターとして受け入れます。
'valueFactory'デリゲートは、キャッシュエントリの有効期限が切れた場合に、(Delivery / Preview APIエンドポイントを呼び出すことによって)新しいキャッシュエントリを構築するために使用されます。 'dependencyListFactory'は、そのエントリを読み取り、現在のエントリが依存するエントリの識別子のコレクションを返す責任があります。 CachedDeliveryClientには、「valueFactory」パラメーターと「dependencyListFactory」パラメーターの両方に固有のメソッドがあります。
CreateEntry メソッドは、「dependencyListFactory」を呼び出し、識別子を使用して、すべての依存関係のダミーキャッシュアイテムを作成します。各ダミーエントリは、 キャンセルトークンをサブスクライブする他のエントリに対応するキャッシュエントリの無効化をアドバタイズするCancellationTokenSourceオブジェクトを保持します。これは、.NETCoreで依存関係が処理される方法です。
最後に、InvalidateEntryメソッドは、特定のキャッシュエントリと、それに依存するすべてのエントリを無効化(クリア)します。 InvalidateEntryメソッドは、WebhookControllerクラスによって呼び出されます。
CachedDeliveryClientクラス
GetItem(s)Asyncメソッドは、CacheManagerを呼び出すだけです。たとえば、以下は、GetItemAsyncメソッドの強く型付けされたオーバーロードのコードです。
'dependencyListFactory'インスタンスは次のようになります(GetDependencies メソッド):
AddModularContentDependenciesメソッドおよびその他のバックエンドメソッドは、ModularContentプロパティからコードネームを抽出するために動的型に依存するだけです。
WebhookControllerクラス
コントローラの仕事は単純に次のとおりです。
•署名を確認します(KenticoCloudSignatureActionFilterを介して)
•KenticoCloudアーティファクトのタイプとそのコードネームを確認します
•必要に応じて、InvalidateEntryメソッドを呼び出します
テスト時間
テストすることは基本的に2つありました。
- キャッシュにすべての依存関係が設定されるかどうか
- WebhookControllerの呼び出しがキャッシュエントリを無効にする場合
すべてのModularContentアイテムのダミーエントリを含め、キャッシュに正しく入力されました。リストの応答の場合、リスト内のすべてのコンテンツアイテムは、対応するダミーエントリを生成しました。したがって、モジュラーコンテンツまたはリストのいずれかのアイテムが廃止された場合、リスト全体が適切に無効化されます。
WebhookControllerの呼び出し時に、キャッシュされたアイテムとリスト(つまり、キャッシュエントリ)は最初に無効とマークされ、次にパージされました。 MemoryCacheのGetメソッドは、古いキャッシュエントリではなく「null」を正しく返しました。その結果、アプリは新しいコンテンツを取得しました。依存関係の1つが無効になったときに、キャッシュエントリも削除されました。
すべてが設定され、完了しました。
コードを取得する
もちろん、サンプルアプリのコードは、GitHubの一般的な記事のサンプルリポジトリから取得できます。また、機能をボイラープレートテンプレートにマージすることも計画しています。
前進する
改善できることがいくつかあります。たとえば、Kentico Cloudで基になるコンテンツタイプが変更されると、キャッシュ内のコンテンツアイテムが無効になる可能性があります。それを見たい場合は、以下のコメントまたはフォーラムでお知らせください。