こんにちは!たつみんです!
今日はOkta WorkflowsでAPIを実行する際のページネーション処理について試行錯誤した記録です。
話の発端は以下のブログ記事をお客様に紹介したところGUIで確認できるデータと差分が発生するというお問合せをいただきました。
あらためてAPIリファレンスを確認してみると/api/v1/devices
を実行した際に1度に取得できるレコード数が最大で200件でした。そして上記で紹介したOkta Workflowsでは200件以上のレコードがある場合を想定していなかったため、取得しきれなかったレコードがありました。
ページネーションとは?
今回のブログ記事のキーポイントであるページネーションについて簡単に解説します。私もAPIに精通しているとは言えないのであくまで本ブログ記事の理解促進のための共通認識としてお伝えできればと思います。
ページネーションでは、今回のAPI /api/v1/devices
を実行しレコードを取得するケースを例にあげると、レコード全件を一度に返すのではなく小さな単位(ページ)に分割して返します。デフォルトでは1ページは最大200件なので、200件以上レコードがある場合はResponseのHeadersに201件目以降のレコードを取得するためのリンクが発行されます。401件目以降のデータがある場合はさらに新しいリンクが発行されます。
具体的には以下のようになリンクが生成されます。
- 201件目から400件目
<https://<yourOktaOrgUrl>.okta.com/api/v1/devices?after=xxx>; rel="next"
- 401件目から600件目
<https://<yourOktaOrgUrl>.okta.com/api/v1/devices?after=yyy>; rel="self"
また次のページがある場合はリンクにはrel="next"
という表示もあります。最後のページの場合はrel="self"
となり終端であることを示します。
このようにページネーションによって区切られたレコードでは、リンクを辿っていくことで最終的にレコード全件を取得することができます。
Okta Workflowsでの処理
ページネーション処理をOkta Workflowsで実現する方法を調べてみるといくつかのサンプルFlowを見つけることができました。共通して言えるのはページネーション処理を実施するHelper Flowを作成し、そのFlowが自分自身を呼び出すことで実現するという内容です。
今回は以下のサンプルFlowを参考にカスタマイズし、冒頭で紹介したDeivce情報を取得するFlowをアップデートします。
サンプルFlowの確認
まずはサンプルFlowの挙動を確認してみます。
- トリガーはHelper Flowカードを選択し、フィールド
url
を定義します。このフィールドは10.のCall Flowカードでこのトリガーを再度呼び出す時に渡される値を受け取るようにするためです。(カード解説) - OktaアプリケーションのCustom API ActionカードでRequestのRelative URLは1.のurlを指定しています。またOptionsではGETを指定しています。
- Getカードで2.でAPI実行した際のResponseのHeadersからlinkを取り出します。
- Findカードで3.で取り出したLinkに
rel="next"
が含まれるかを調べます。含まれる場合はその開始位置を返します。 - Continue Ifカードで4.の戻り値が-1より大きい場合つまり
rel="next"
がある場合は以降の処理を継続します。(カード解説)
- Findカードで3.で取り出したLinkに
/api/v1
が含まれるかを調べます。含まれる場合はその開始位置を返します。 - Findカードで3.で取り出したLinkに
>
が含まれるかを調べます。含まれる場合はその開始位置を返します。 - Text Segmentカードで3.で取り出したLinkを6.と7.の範囲で切り出します。
- Replaceカードで8.で切り出したURLに
+
が含まれる場合にスペースに置き換えます。 - Call FlowカードでこのFlow自体を再度呼び出します。その際に9.の出力であるURLを渡します。
処理のポイントは4.でLinkにrel="next"
が含まれるかどうか、そしてその結果によって5.で以降の処理を行うかどうか分岐をしている点です。そして10.で自分自身を呼び出すという処理です。
ただしこのFlow単体ではトリガーがHelper FlowであるためRunボタンを押して最初のURLを手動で入力する必要がああります。
既存Folwをページネーション対応にアップデートしてみる
以前作成したFlowをページネーション対応にアップデートしてみます。
このブログ記事ではテーブルの作成やOkta Workflows OAuthの設定については省略していますのでゼロから構築する場合は冒頭で紹介しました以前のブログ記事もご参照ください。
1.1 Main Flow
まずは定期実行のために以下のMain Flowを作成します。
- トリガーはScheduled Flowとし1日1回実行するようにしています。
- 初期化処理としてClear Tableを実行
- Call FlowでサンプルFlowを呼び出します。この時urlとして
/api/v1/devices?limit=15
を渡しています。
今回の検証環境では200台もDeviceが登録されていないため1回あたりの取得件数を15件に限定し、ページネーション処理が正しく行われるかを観察するためにパラメータとしてlimit=15
を付加しています。
1.2 paginate
ここではサンプルFlowのCustom API Actionの直後にFor Eachの処理を追加し、1.3 Device処理を呼び出してループ処理を実施します。
後半部分は全く変更していません。
1.3 Device処理
以前のブログ記事のFlow2と全く一緒です。
1.4 User処理
以前のブログ記事のFlow3と全く一緒です。
まとめ
このようにもともと作成していたFlowの大部分を変更することなくページネーション処理に対応することができました。また、/api/v1/devices
のドキュメントをよくよく確認してみるとlimitについての部分でデフォルトは200件取得ですが、推奨値は20件との記載があります。実装する際には1.1 Main Flowで指定するURLは/api/v1/devices?limit=20
としておくとよいでしょう。
Default: 200
https://developer.okta.com/docs/api/openapi/okta-management/management/tag/Device/#tag/Device/operation/listDevices
A limit on the number of objects to return (recommend 20)
大規模なデータを扱う場合はページネーション処理への対応が必須となるためこの記事がみなさんのお役に立てることを願っています。
それでは今日はこのへんで!また別の記事でお会いしましょう!