kintoneのレコード一括取得offset上限値を超えて指定するとどうなるのか

前回の記事では、レコード一括取得の「レコードIDを利用する方法」で1万件以上取ってこれるのか試してみました。

https://qiita.com/juri_don/private/63da7dc6e909cba29858


今回は、offsetが上限値である10,000以上を超えるとどうなるのか？人柱になって試してみました。
（よいこの皆さんはやってはダメですよ）

# アプリの準備

[前回の記事](https://qiita.com/juri_don/private/63da7dc6e909cba29858#アプリの準備)で作成したアプリに、更に1万件レコードを読み込ませてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/18f3d377-13bf-46c9-86ed-33ffb251d765.png)

# JavaScript
[サンプルコード](https://developer.cybozu.io/hc/ja/articles/360031191791#use_offset)のvarをconstやletに変えました。（最初からoffsetを10,000以上で呼び出しても良かったなと思う）

```js
const getRecords = function (_params) {
  const MAX_READ_LIMIT = 500;

  const params = _params || {};
  const app = params.app || kintone.app.getId();
  const filterCond = params.filterCond;
  const sortConds = params.sortConds;
  const limit = params.limit || -1;
  const offset = params.offset || 0;
  const fields = params.fields;
  let data = params.data;

  if (!data) {
    data = {
      records: [],
    };
  }

  let willBeDone = false;
  let thisLimit = MAX_READ_LIMIT;
  // getRecords 関数の呼び出し側で、レコードの取得件数を指定された場合は
  // 取得件数を満たせば終了するように willBeDone を true にする
  if (limit > 0) {
    if (thisLimit > limit) {
      thisLimit = limit;
      willBeDone = true;
    }
  }

  const conditions = [];
  if (filterCond) {
    conditions.push(filterCond);
  }

  const sortCondsAndLimit =
    (sortConds && sortConds.length > 0
      ? " order by " + sortConds.join(", ")
      : "") +
    " limit " +
    thisLimit;
  const query =
    conditions.join(" and ") + sortCondsAndLimit + " offset " + offset;
  const body = {
    app: app,
    query: query,
  };
  if (fields && fields.length > 0) {
    body.fields = fields;
  }
  return kintone
    .api(kintone.api.url("/k/v1/records", true), "GET", body)
    .then(function (resp) {
      data.records = data.records.concat(resp.records);
      const _offset = resp.records.length;
      if (limit > 0 && limit < _offset) {
        willBeDone = true;
      }
      // 取得すべきレコードを取得したら終了する
      if (_offset < thisLimit || willBeDone) {
        return data;
      }
      console.log("offsetの値", offset, _offset);
      // 取得すべきレコードが残っている場合は、再帰呼び出しで残りのレコードを取得する
      return getRecords({
        app: app,
        filterCond: filterCond,
        sortConds: sortConds,
        limit: limit - _offset,
        offset: offset + _offset,
        fields: fields,
        data: data,
      });
    });
};

kintone.events.on(["app.record.detail.show"], (event) => {
  const params = {
    app: 【アプリID】,
    sortConds: ["$id asc"],
  };
  getRecords(params).then((resp) => {
    console.log(resp);
  });
});
```

# 結果

あれ？1万件以上取れてる。20,100件取得できているぞ👀？上限値1万というのは！？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/c416778a-1a90-2fe0-5a89-68d1925b9415.png)


と思いましたが、一覧画面に戻ると下図のように表示されました。

`パフォーマンスに影響を与える処理が検知されました。`

「赤」ではなくて「水色」で警告してくれるところに、優しさを感じました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/7cd66840-20af-0373-2ba8-130caa289141.png)


お知らせページによると・・・・

https://cs.cybozu.co.jp/2019/006924.html


>2020年7月の定期メンテナンス以降、レコード一括取得APIでoffset上限値10,000を超える処理を行った場合、そのリクエストは処理されなくなります。
>ただし、2020年7月の定期メンテナンス以前からご利用いただいているお客様については、kintone管理者および該当のアプリ管理者の画面上に「上限値を超過した旨」が警告表示され、リクエストは処理される仕様となっています。

とあり、私の開発環境は2020年7月の定期メンテナンス以前から使用しているので警告表示だけされたということのようです。2020年7月の定期メンテナンス以降のユーザーさんだとリクエスト自体が処理されないようですね。

というわけで、1万件以上のレコードを取得したい時は「offset を利用する方法」ではなく、推奨されている「カーソル API を利用する方法」や、kintone REST API Client を使いましょう！

おしまい。