
はじめに
SAP BTPとSAP SuccessFactorsとの連携でWebAPIの「OData」で開発を行う際、「$top / $skip」というパラメータを用いてページネーション(大量のデータを分割して取得するデータ取得方法)を行うことができます。
しかし「$top / $skip」を用いたページネーションでデータ取得を行っていると、想定していた件数と異なる件数が返却される事象が発生し、ページネーションについての理解が浅かった私は原因解明にとても苦労しました。
本記事では私が開発中に直面した事象とその対応策について解説いたします。
※ODataAPIの基本情報やその他のquery optionsについての情報は以下記事をご参照ください。
・【OData】SAPのアドオン開発のデータ連携を簡単に!OData APIについて
・初心者がつまづきやすいSuccessFactors APIの歴管理を徹底解説!query options(fromDate, toDate, asOfDate, filterParentDate)を使いこなす
$top / $skipについて
事象を説明する前に、タイトルにも記載している$top / $skipというパラメータについて説明いたします。
$top
このパラメータは、1回の取得リクエストで返却されるデータ件数を制御します。
指定できる最大数値とデフォルト($topパラメータの指定なし)は同じく1000レコードを返却します。
$skip
このパラメータは、取得リクエスト時にレコードの上から数えて何件分スキップするか、を指定することができます。
例)GET https://sandbox.api.sap.com/successfactors/odata/v2/EntityA?$top=100&$skip=200
上記例のクエリの場合、取得されるレコードのうち、最初の200件をスキップした100件分のレコードが取得されるため、201件目~300件までの100件のレコードが取得されます。
これらのパラメータを使ったバッチ処理にてデータ取得を行っていたところ、次の事象を確認いたしました。
発生した事象
「$top=1000を指定しているのに、返却されたレコード件数を数えると約990件しかない…」
バッチ処理にてデータを取得し、取得したデータを加工して更新する処理の中で、実際に処理された件数が想定される処理対象件数より少ない事象が発生しました。
データベースにレコードは1000件以上あるのに、1度のリクエストで返却される件数が1000件以下となっているため、処理対象レコードの一部しか処理できていなかったことが原因だったのです。
なぜ$topに指定した件数と返却される件数に差異があるのか、SAPの公式ヘルプを確認しましたところ、以下の記述がありました。
SAPヘルプの記述
ダーティデータがある場合、ビジネスルール後の検証が適用される可能性があるため、クライアント側のページ設定では、$topパラメータで指定した正確なレコード数がすべてのページで返されるとは限りません。これは、データが失われることを意味するわけではありません。データセット全体のレコードの合計数は影響を受けません。データの問題を回避するには、クエリに$orderbyパラメータを追加してください。(引用元:Client-Side Pagination)
⇒データの問題や、SuccessFactorsの仕様により、クライアント側のページネーションである$top / $skipでのページネーションはダーティなデータ(※1)の存在やビジネスルール(※2)の影響によって必ずしも$topに指定した件数を返却するものではないということがわかりました。
加えて、$top / $skipでのページネーションはスクロールするたびにデータを読み込むテーブルを開発する際など、主にUIでの使用が推奨されていることも判明いたしました。
※1.ダーティなデータ
ページネーションを行う際、ロードしたタイミングより後にデータに変更が起こり、整合性が取れていない状態のデータ。
※2.ビジネスルール
SAP SuccessFactors Employee Central(通称EC)にて、特定のデータの追加、変更、削除をトリガにして、特定のアクションを行うことができる。ビジネスルールとは、何をトリガにどのようなアクションを行うか、を定めている。
例)『異動に伴い、所属部署を変更(トリガ)⇒所属長を異動先の上長に自動で更新(アクション)』(ビジネスルール)
対応策
私が開発していた機能ではUIを使用するのではなく、バッチ処理にて大量のデータを取得し、加工して更新するものであったため「$top / $skip」ではなく、サーバ側のページネーションである「paging=snapshot」というパラメータを付与することで対応いたしました。
「paging=snapshot」というパラメータは大量データの取得&複雑なクエリを実行する際に推奨されるパラメータであり、以下のように使用できます。
例)GET https://sandbox.api.sap.com/successfactors/odata/v2/EntityA?paging=snapshot
上記クエリを実行してデータ取得を行うと、次ページがあれば__nextというパラメータとともに「$skiptoken」という項目が返却されるため、この「$skiptoken」を使用することでページングを行います。
例)GET https://sandbox.api.sap.com/successfactors/odata/v2/EntityA?paging=cursor&$skiptoken=<返却値>
この修正によって、取得想定件数とクエリによって返却されるデータ件数の差異がなくなり、事象の解決に至りました。
おわりに
SAP BTPとSAP SuccessFactorsとの連携でWebAPIの「OData」で開発を行う際、ページネーションを考慮することは必要不可欠の事柄かと思います。
しかしながら、ページネーションのパラメータの特性について理解していない状況では、今回ご紹介した「$topに指定した値と返却される件数が異なる」という事象などが発生した際に原因調査にとても時間がかかります。
開発を行うにあたって、同様の事象が発生した方やこれから開発を始めようとされる方に本記事が参考となれば幸いです。
今回は事象の解説とその対応策の紹介を行いましたが、SuccessFactors APIにおけるページネーションについて、使用できるパラメータと推奨される選択方法については次回の記事で投稿予定ですので、そちらもご覧いただければ幸いです。
最後まで閲覧していただき、ありがとうございます。
投稿者プロフィール

-
2021年入社、BS事業部BSグループに所属。
SAP BTPでのSide-By-Side開発に携わっています。
開発業務を通じて得たSAP BTPの技術に関する記事を投稿していければと思います。
最新の投稿
SAP2025.01.27【SAP BTP】SuccessFactors APIにおけるページネーション解説[$top/$skip][paging=cursor][paging=snapshot]の使い分け
SAP2024.12.10【SAP BTP】【SuccessFactors】データ取得条件「$top=1000」は必ずしも1000件のレコードを返却するとは限らない
SAP2024.07.08初心者がつまづきやすいSuccessFactors APIの歴管理を徹底解説!query options(fromDate, toDate, asOfDate, filterParentDate)を使いこなす