kintone の全アプリを毎日まるごと取得しようとして、API リクエスト枠の設計で学んだこと

kintone のデータを毎日まるごと別の場所に取り続ける、という処理を書いています。
全アプリのレコード・添付ファイル・コメント・アプリ設定を毎日1世代として取得し、前日と突き合わせて差分を出す、という形です。

作ってみると、難しいのは取得そのものではなく API リクエスト枠の設計 でした。
自分が最初に誤解していたことが3つあったので共有します。同じことをやる方の役に立てば幸いです。

1. リクエスト数のリセットは 0時ではなく JST 9:00

1アプリ1日あたりのリクエスト数に上限がある、というのは知っていたのですが、集計期間が 9:00〜翌8:59 だというのを見落としていました。0時で切り替わるものだと思い込んでいて、夜間バッチの時刻を決めるときに前提がずれていました。

夜中の2時台に回すと、「利用者が日中に使ったあとの残り枠」 を使うことになります。枠が欲しいだけなら9時直後のほうが有利ですが、それは業務時間帯に負荷をかけることになるので、結局は夜間のままにしました。順番としてはこれでいいと思っています。

2. 上限を超えても、その場でエラーにはならない

これも誤解していました。超えた瞬間に 4xx が返ってくるものだと思っていたのですが、実際に起きるのは 翌日9時ごろ、cybozu.com のストア管理者に超過メールが届く ことでした。公式には「他のユーザーの環境に重大な影響を及ぼす場合、API処理を中断することもある」とも書かれています。

即座に止まらないぶん、気づくのが利用者側になる のが厄介だと思いました。ツールを入れた結果、管理者に警告メールが飛ぶのは避けたいので、自分の側で上限を持つ ことにしました。既定は公式上限の半分にして、残りは利用者の業務のために空けています。

3. コメントの取得だけ桁が違う

レコード本体は 1リクエスト 500件なので、1万件のアプリでも 20リクエストです。ところが コメントは一括取得のエンドポイントが無く、アプリとレコードを1件ずつ指定 します。1リクエストで取れるのは最大10件。

レコード 10,000件のアプリを1回走査する場合
  レコード本体 :    20 リクエスト
  コメント     : 10,000 リクエスト(1レコード1リクエスト以上)

これだけで1日の枠を使い切ります。しかも コメントの投稿・削除ではレコードの revision も更新日時も動かない ので、「前回から変わったレコードだけ見る」という安い差分が取れません。毎回全件なめることになります。

結局、全部いっぺんに取るのは諦めて、1日に使う予算を決めて、前回の続きから少しずつ舐める(カーソルを持つ)形にしました。

おまけ: アプリ設定は 17 か所に散らばっている

ついでに踏んだ話です。「アプリの設定」を一式取ろうとすると、エンドポイントが 17 本ありました。

app / app/settings / app/form/fields / app/form/layout / app/views /
app/status / app/actions / app/reports /
app/notifications/general / app/notifications/perRecord / app/notifications/reminder /
app/acl / record/acl / field/acl /
app/customize / app/plugins / app/adminNotes

アクセス権だけで3本(アプリ・レコード・フィールド)あります。
また /k/v1/app.json だけアプリ指定のパラメータが id で、他は app でした。ここを揃えて書いて 400 (CB_VA01) を出しました。

権限やプランによって 403/404 が返るエンドポイントもあるので、取れなかったものは握り潰さず、理由つきで残す ようにしています。「取れなかった」と「変わっていない」を混ぜると、あとで差分を見たときに嘘をつくことになるので。

伺いたいこと

枠の使い方について、皆さんがどうされているか知りたいです。

  • 定期的に全件を取りにいく処理で、1日に使うリクエスト数をどれくらいに抑えていますか
  • 利用者の業務と枠を分け合う前提で、実行時刻はどう決めていますか
  • コメントのように差分が取れないデータを扱うとき、他に手はあるでしょうか

(株式会社VILLION で kintone のデータ保護まわりを作っています)

(直接的な回答じゃなくてすいません、アイディアとして)
たしかに場合によってはシビアですよね、cli-kintoneなどで一度データをエクスポートしたあとに処理をする、などをするとAPIをCallする回数は減らせそうだなぁとはおもったりしてます

mura さん、ありがとうございます。アイディアとして助かります。

気になったので cli-kintone のドキュメントを読んでみたのですが、私のケースだと枠はあまり減らなさそうでした。理由を2つ書きます。間違っていたら指摘いただけると嬉しいです。

1. cli-kintone も中では REST API を呼んでいる

record export のドキュメントに、--condition と --order-by は「@kintone/rest-api-client の getAllRecords() に渡される」と書かれていました。裏で叩いているのは同じ REST API なので、1アプリあたりのリクエスト枠は同じように消費される、という理解です。

とはいえ、自前でページングを書くより素直で安全なのは確かだと思います。添付ファイルを --attachments-dir で一緒に落とせるのは、自分で fileKey を回すより明らかに楽でした。

2. 枠を食っていたのは、レコードではなくコメントだった

これは私の書き方が悪かったのですが、レコード本体は 500件/リクエストなので1万件でも20リクエストで、そこは最初から問題になっていませんでした。効いていたのはコメントのほうです。

record export のオプションは --app / --attachments-dir / --condition / --order-by / --fields / --encoding で、コメントは対象外のようでした。なので一度エクスポートしてから処理しても、コメントは別途 /k/v1/record/comments.json を1レコードずつ叩くことになり、1万リクエストのほうは残ってしまう、という理解です。


逆に言うと、コメントを諦められるなら cli-kintone で十分だと思いました。レコードと添付だけなら、自前で書く理由はあまり無さそうです。私の場合は「消えたコメントに気づけること」が目的なので諦められず、結局「1日の予算を決めて前回の続きから舐める」に落ち着きました。

もし「コメントをまとめて取る」別の手をご存じでしたら、ぜひ教えてください。そこだけが今も解けていません。

ですね、cli-kintoneも裏ではAPIを呼んでいるだけなので、一旦サーバーや手元におとして読み取り・修正することにより、APIの回数を減らしうるのではないか?というような意味合いでした:folded_hands:

コメントに関しては、おっしゃるとおりで、僕はコメントの全取得などはあきらめています…(本来であればコメントもバックアップしたい要望があります)
一方で、コメント機能は投稿者が削除できたり版管理はできませんし、あくまで「コメント」ですので、業務上クリティカルな情報なら、APIの制限も考えてやはりレコードの中に収めるのが筋なのかもな、と思うようにしています…

サイボウズ公式としても、コメントに関しては

一方で、その案件に紐づく個別の質問や状況確認等は後々の分析等が不要だと考えられるので、当該レコードのコメント欄でやり取りを行うのが好ましい。

として、いつ消えたとしても問題ないよね、という位置づけなので、諦めるしかないかなと思いますね。それが管理かと言われるとモヤっとするところはありますが……

住田さん、ありがとうございます。SIGNPOST、恥ずかしながら読めていませんでした。原文を読んできました。

引用いただいた一文の、すぐ後ろにこう続いていました。

コメント欄に残しておくことでレコードと紐付けて集約されるので、後に新規メンバーや第三者がレコード参照する際に、メッセージで担当者に状況の個別確認をする必要がなくなる。

自分はこれを読んで、「後々の分析等が不要」は分析・再利用の効率の話であって、消えてよいとまでは書いていないのかな、と受け取りました。むしろ「残しておくことで〜必要がなくなる」と、後から参照される前提になっているように見えます。

とはいえ自分に都合よく読んでいる自覚もあるので、住田さんが「モヤっとする」と書かれた感覚のほうが実務に近いのだろうとも思います。設計の指針としては「分析・再利用するものはレコードに入れろ」で、それでも現場のコメント欄には判断の経緯が溜まってしまう、という話なのかなと。

muraさん、「本来であればコメントもバックアップしたい要望があります」が、いちばん効きました。自分は「実は誰も困っていないのでは」と疑っていたので。諦められているだけで要望自体はある、という状態なら、やることは変わらないなと思えました。

版管理が無く投稿者が消せる点もおっしゃるとおりで、だから kintone の中では解けず、外から定点観測するしかないと思っています。取りに行くと今度は枠を食う、というのが本当に厄介なところです。

おふたりとも「諦めている」という言い方をされているのが印象的でした。諦めずに済むとしたら、枠を食わずにコメントの変化を知る方法があるかどうかだと思うのですが、通知やWebhookを含めても、削除を検知できる口は見つけられていません。もしご存じでしたら教えてください。

確かに「いつ消えたとしても問題ない」は拡大解釈すぎたかもしれません。すみません。

ただ、 @mura さんの意見とも被りますが、コメントでやり取りした内容の中から重要なことや確定したことは、定型化して残す (=レコードとして残す) というのが基本方針のように見えるので、そういう意味で API やエクスポートからは触りづらくしているのかも、とは思っています。判断の理由はレコードに残すべきだけど、その理由の検討自体は機械的に分析する必要がない、という感じ?

コメントに重要な判断材料が残っていたり、レコードの情報の補完として運用することもあるので、 API で取れるようになるほうが良いとは思います。また最近では生成 AI が発達して、フロー情報も分析しやすくなってるという面でも、機械的に読めたほうがいいものではありますよね。環境の変化も含めて、サイボウズさんに要望を投げて口を作ってもらえるよう促すのがいいのかな……?

住田さん、わざわざ訂正いただいてありがとうございます。こちらも引用元だけ見て判断しかけていたので、原文に当たってよかったです。

「API やエクスポートからは触りづらくしているのかも」という見立てについて、材料を1つだけ足させてください。

コメントは REST API に口自体はあります(取得・投稿・削除の3本)。なので「意図的に触らせない」というより、一括で取る口が無いだけ、という形に見えています。閉じる方針なら取得の口も置かないはずなので。差分が取れないのも revision が動かない結果であって、コメントを隠すための仕組みには見えません。

そう考えると穴は思ったより狭くて、埋め方も絞れる気がしています。

もう1つ、方針ではなく実務の話として最近気づいたことがあります。解約のときに効いてきます。

cybozu.com の登録データは解約日の翌日から30日後に消去され、ストアを退会した場合は30日を待たずその時点で消える、と公式に書かれています。つまり解約する側には、日付の決まった持ち出し作業があります。ところが標準の書き出しにコメントは含まれず、cli-kintone の record export にもコメントのオプションがありません。結果として、レコードは CSV に残るのに、なぜそう決まったかだけが残らない状態で環境が消えます。

「重要なことはレコードに定型化して残す」が基本方針だとしても、実際にはコメントに判断の理由が残っている環境はあるので、そこは運用の良し悪しではなく、持ち出す口が無いことの帰結だと思っています。

要望を出すのは賛成です。形は2つ考えられて、

  • コメントの投稿・削除で revision が動くようにする
  • コメントの一括取得エンドポイントを足す

前者は既存の楽観ロックや「revision が変わった=レコードが変わった」という前提の処理を壊すので、通りにくいのではと思っています。後者のほうが影響範囲が小さく、こちらが欲しいものもほぼ満たせます。

伺いたいのですが、この種の要望は実際どこに出すと届くものでしょうか。サポート経由なのか、このコミュニティなのか、別の窓口があるのか。出し先を間違えて立ち消えるのはもったいないので、経験のある方の肌感を教えていただけると助かります。

このコミュニティもみられてるとおもいますし、要望をだすフォームもあるので、そこでも要望をあげるとよさそうです!!