ページネーションについて

お世話になります。
質問させていただきたく存じます。
よろしくお願いいたします。

実現したいこと

現在、kintoneのアプリ内に家財一覧を登録しており、JavaScriptで呼び出してドロップダウンに埋め込みたいと考えています。

エラーなどは発生しているか

エラーは発生していませんが、全レコード136件が読み込めていない状況です。
$masterDataは「Array(100)」となっています。(配列内容については問題ありません))

仕様上、一度の処理に対して100件が上限というのは確認したのですが、
ページネーションを実行すると500件まで読み込めると出てきたので
確認に参りました。

確認事項

認識の違いがあるといけないので確認なのですが、ページネーションとは、
処理1. 1件目から100件目を読み込んで配列に保存
処理2.101件目から200件目を読み込んで配列に追加保存
処理3.件数がなくなったら終了し、なくなっていなかったら処理2を繰り返す
という認識でよろしいでしょうか。

ソースの貼付

現在動作させているページネーションの所を抜粋します。

<php?
function fetchKazaiMaster() {
    $url = 'https://' . KINTONE_SUBDOMAIN . '.cybozu.com/k/v1/records.json?app=' . KINTONE_APP_ID_KAZAI . '&size=500'; // 最大500件取得

    $headers = [
        'X-Cybozu-API-Token: ' . KINTONE_API_TOKEN_KAZAI,
    ];

    $allRecords = [];
    $next = null;

    // nextがない間はループ
    do {
        $requestUrl = $url;
        if ($next) {
            // nextがあればURLに追加
            $requestUrl .= '&next=' . $next;
        }

        // cURLでリクエスト
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $requestUrl);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            curl_close($ch);
            return []; // エラーがあれば空配列を返す
        }
        curl_close($ch);

        $data = json_decode($response, true);

        if (isset($data['records'])) {
            $allRecords = array_merge($allRecords, $data['records']); // 現在のレコードをまとめる
        }

        // 次ページのURLがあるかを確認
        $next = isset($data['next']) ? $data['next'] : null;
    } while ($next); // nextがある限りループを続ける

    return $allRecords; // すべてのレコードを返す
}

$masterData = fetchKazaiMaster();
?>

まず、全件取得をしたい、ということであれば

認識の違いがあるといけないので確認なのですが、ページネーションとは、
処理1. 1件目から100件目を読み込んで配列に保存
処理2.101件目から200件目を読み込んで配列に追加保存
処理3.件数がなくなったら終了し、なくなっていなかったら処理2を繰り返す
という認識でよろしいでしょうか。

この認識はまちがってません、なくなるまでループで取得します。
これについては書いてあるとおり無くなるまで続けるので500件という制限は特にありません(ただし、APIの件数Limitに抵触するともちろんそこでとまる 参考


つぎに、「500件」という数字についてですが、kintone REST APIのレコード複数取得APIではデフォルトで100件のデータが取れます。が、クエリのlimit500件まで指定できます。
なので、そこと話が混同してしまっているのかな?というのを感じました


まとめると、全件取得したい場合は述べられている通り、なくなるまで取得のループを繰り返す、
500件以下で収まるなら querylimit 500 とすればOK、ということになります。
(なお、ループする際にも500を指定したほうがループ数は少なくなるのでそのほうがいいでしょう)

2 Likes

mura様

ご回答ありがとうございます。
質問の仕方が良くありませんでした。
状況的には
kintone外(kintoneとは別サーバーにあるHTMLファイルの中にJavaScriptを書いている状況です)

今回は500件以下で収まりますので「query に limit 500」をとの事でしたのでコードをこのように書き直しました。

$headers = [
    'X-Cybozu-API-Token: ' . KINTONE_API_TOKEN_KAZAI,
];
$params = [
    'query' => 'limit 500', // (最大500)
];

このように修正しましたが、100件を超えて136件の取得が出来ておりません。
Chromeのデベロッパーツールで配列を確認しましたが「Array(100)」と表示されます。

私自身の勘違いがあるのでしょうか。
ご教示くださいませ。よろしくお願いいたします。

kintone外(kintoneとは別サーバーにあるHTMLファイルの中にJavaScriptを書いている状況です)

そもそもコードはPHPのコードに見えますが…どうでしょう?
まぁそれはおいておいて、

問題の切り分けのために実際にAPIに接続するためのURLがどうなっているか?デバッグはできますか?
URLが下記のような感じになっているかですね。
https://ドメイン.cybozu.com/k/v1/records.json?app=1&query=limit 500

おそらくですが、paramsで指定したものがURLのパラメータにのってないんじゃないかなとおもいます。
動作未検証ですが、こんな感じで指定するとどうでしょうか

$query = urlencode('limit 500');

$url = "https://{サブドメイン}.cybozu.com/k/v1/records.json?app={$app}&query={$query}";

// 以下cURLでのリクエスト処理
1 Like

mura様

ご回答ありがとうございます。
kintoneと別のサーバーでHTML内にJavaScriptとPHPで書いています。というのが正解でしたね。失礼しました。

例に挙げて頂いた、

$query = urlencode('limit 500');
$url = 'https://' . KINTONE_SUBDOMAIN . '.cybozu.com/k/v1/records.json?app=' . KINTONE_APP_ID_KAZAI . '&query={$query}'; // 最大500件取得
echo $url;

を実行しますとブラウザ画面に、

https://ドメイン.cybozu.com/k/v1/records.json?app=81&query={$query}

と表示され取得できていませんでした。

次に、

$url = 'https://' . KINTONE_SUBDOMAIN . '.cybozu.com/k/v1/records.json?app=81&query=' . urlencode('limit 500'); // 最大500件取得
echo $url;

を実行しますとブラウザ画面に、

https://ドメイン.cybozu.com/k/v1/records.json?app=81&query=limit+500

と表示され件数は100件取得されています。

よろしくお願いいたします。

を実行しますとブラウザ画面に、
https://ドメイン.cybozu.com/k/v1/records.json?app=81&query={$query}
と表示され取得できていませんでした。

シングルクォートとダブルクォートでは文字列の扱いが多少ことなるので、私が挙げた例のようなquery={$query} という表現を使いたい場合はダブルクォートでくくってください。
(もちろん、やられてるようにドット .でつなぐ形式でも問題ないので大丈夫です)


さて、本題ですが、
自分の方でもねんのため下記のようにcURLで取得するコードをかいてみましたが、ちゃんとクエリの件数は有効になってました。(100件以上取得できる
記述にどこかあやまりがあるかもしれませんので、見直してみてください!

$app = 123;
$query = urlencode('limit 500');
$url = "https://ドメイン.cybozu.com/k/v1/records.json?app={$app}&query={$query}";
$headers = ['X-Cybozu-API-Token: xxxx'];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);

// レスポンスをjsonにデコードしてレコード数をカウント
$data = json_decode($response, true);
count($data['records']);
echo count($data['records']);

mura様

ご回答ありがとうございます。
mura様のご提示いただいたソースで件数は取得できました。

ソースを見直してトレースしたところ、

$requestUrl = $url;

これが悪さをしていたようです…。
ケアレスミスですね。ありがとうございました!

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。