先日AzureのAPIを.NETのSDKから呼び出したのだけれど、ページネートを忘れていてAPIの結果が欠落した。
Fix pagenate by 7474 · Pull Request #2 · 7474/PostAzureCostToMackerelFunction · GitHub でFixした(つもり)。
ページネートという概念は多量のデータをAPIで扱う際には必須な要素ではあるけれど、とりあえず全部欲しい場面もある。
その場合は IPage<T>
を AsContinuousCollection
すればいいようだった。
IPageには次の結果を得るためのNextPageLinkプロパティがある。愚直に実装する場合は、その値があればXxxNextメソッドに渡すことで次の結果を得られる。
AsContinuousCollection拡張メソッドはそれをよしなに処理してIEnumerableとして列挙できるようにしてくれる。
元々全量返すメソッドがあるものもある
APIによっては全データを返却するメソッドが用意されているものもあるようだ(ずるい)。が、今回使っていたAzure Consumption APIの.NET SDKには用意されていない(残念)。
深く考えず(ドキュメントや実装を眺めず)に見分けるには、返却値の型を見れば良さそうだ。IPage<T>
ならページネート処理が自前で必要で、IEnumerable<T>
なら多分全データが返ってくるはずだ。
ずるいやつ
深くというか、普通に考えてみると ずるいやつ はAzure SDK for .NETではなくAzure Management Libraries for .NETだった。
The Azure Management Libraries for .NET is a higher-level, object-oriented API for managing Azure resources. Libraries are built on the lower-level, request-response style auto generated clients and can run side-by-side with auto generated clients.
とのこと。Google翻訳するとこうなる。
.NETのAzure管理ライブラリは、Azureリソースを管理するためのより高レベルのオブジェクト指向APIです。ライブラリは、下位レベルの要求/応答スタイルの自動生成クライアントに基づいて構築されており、自動生成クライアントと並行して実行できます。
OpenAPI仕様から生成しているSDKをベースにして、より使いやすいように手間暇かけて作られているライブラリということらしい。そりゃ、ニッチなAPIには提供されないだろう。
IPage<T>
の内容を全ページ分返す実装は、先に書いた IPagecurrentPage.NextPageLink != null
は !string.IsNullOrEmpty(currentPage.NextPageLink)
でなくていいのか? という気分にはなる)様子。
今回のミスのFixもそれをおパクリする形でやった(つもり)。
結果さっと全ページのデータを取得できた(つもりになれた)。APIの定義と言語としてのインタフェースがしっかりしていると便利だなぁ。
余談
同じAzureのライブラリでも言語(今回は.NET、大体はC#)が違うとページネートへのアプローチが違うっぽい感じがしている。気が向いたら他の言語を見ても面白いかな、と思うだけ思っている。
また、何回も つもり と出てくるのはまだ実データでページネートされていないかららしい。
2020-05-01 追記:
ちょっとだけ他の言語のSDK(Azure SDK とコマンド ライン ツールのダウンロード | Microsoft Azure に載ってるやつ)も観たけれど、どれも不自由なくページネートできそうだった。
JavaScript: https://t.co/qiBkwoYnsm
— 光電/7474 (@koudenpa) 2020年5月1日
Python: https://t.co/aEZIAeBZ87
JavaScriptは全量がコールバックされる様子。Pythonはページを読んでいく必要があるのかな。