kintoneAPIで更新、登録、削除を同時に行うことは可能ですか?

何を実現したいのかを書きましょう

やりたいこと:
アプリAのデータを集計して、アプリBに集計値をデータとして格納する

アプリAの構造
→レコードの中にテーブルを持っていて、月ごとの合計が入っている
例)レコード番号 会社名 テーブル
001 株式会社A [4: 1000,5: 1000,6: 1000]
002 株式会社A [5: 2000,6: 2000,7: 2000]
003 株式会社B [4: 2000,5: 2000,6: 2000]
アプリBの構造
→会社と月ごとにレコードが分かれている
例)レコード番号 月 会社名 金額
001 4 株式会社A 1000
002 5 株式会社A 3000
003 6 株式会社A 3000
004 7 株式会社A 2000
005 4 株式会社B 2000
006 5 株式会社B 2000
007 6 株式会社B 2000

〇上記のレコードが存在しているところで、アプリAのレコード番号002を削除した場合に、アプリB側では削除されたレコードに合わせて減算、レコード削除を行う。
<変更後>
アプリAの構造
例)レコード番号 会社名 テーブル
001 株式会社A [4: 1000,5: 1000,6: 1000]
003 株式会社B [4: 2000,5: 2000,6: 2000]
アプリBの構造
例)レコード番号 月 会社名 金額
001 4 株式会社A 1000
002 5 株式会社A 1000
003 6 株式会社A 1000
005 4 株式会社B 2000
006 5 株式会社B 2000
007 6 株式会社B 2000

起きている事象:
5月分と6月分は減算処理が行われるのですが、7月分は処理が素通りされて処理が終わる。
エラーとしては、PUTとDELETE処理を同時に行っているから?と疑問に思い、相談させていただきました。
仕様として、そのようなルールなどあるのでしょうか?
アプリ間のデータ権限については、下記記載箇所以外の別の箇所に記述したDELETE処理は正常に動作しているので、問題ないのでは?と思っています。
※正常に動作している箇所はDELETE処理のみ記述しています。

<現状の状態>
アプリAの構造
例)レコード番号 会社名 テーブル
001 株式会社A [4: 1000,5: 1000,6: 1000]
003 株式会社B [4: 2000,5: 2000,6: 2000]
アプリBの構造
例)レコード番号 月 会社名 金額
001 4 株式会社A 1000
002 5 株式会社A 1000
003 6 株式会社A 1000
004 7 株式会社A 2000 ←削除されない。。。
005 4 株式会社B 2000
006 5 株式会社B 2000
007 6 株式会社B 2000

発生した問題やエラーメッセージを具体的に書きましょう

finalTotalPriceやexistingRecordにはデータが入っていることは確認できています。
下記コード部分が問題かと思うのですが、修正箇所などご教授いただけますでしょうか。

↓↓↓コードから抜粋↓↓↓

`Object.keys(finalTotalPrice).forEach((key, index) => {
  let thukiValue = parseInt(thuki, 10) + index;
  let price = finalTotalPrice[thukiValue];
  if (thukiValue >= thuki && thukiValue <= endThuki) {
    let existingRecord = getRespB.records.find(record =>
      record[thukiField] && record[thukiField].value === String(thukiValue)
    );
    if (price) {
      if (existingRecord) { // レコードが存在する場合はPUT(更新)処理
        requests.push(
          kintone.api(
            kintone.api.url("/k/v1/record",true),
            "PUT",
            {
              app: APP_B_ID,
              id: existingRecord.$id.value,
              record: {
                [nendoYearField]: { value: nendoYear },
                [nenYearField]: { value: nenYear },
                [thukiField]: { value: thukiValue },
                [torihikisakiId]: { value: compId },
                [torihikisakiName]: { value: compName },
                [mithumoriTotalPriceField]: { value: price }
              }
            }
          )
        );
      } else { // レコードが存在しない場合はPOST(新規作成)処理
        requests.push(
          kintone.api(
            kintone.api.url("/k/v1/record", true),
            "POST",
            {
              app: APP_B_ID,
              record: {
                [nendoYearField]: { value: nendoYear },
                [nenYearField]: { value: nenYear },
                [thukiField]: { value: thukiValue },
                [torihikisakiId]: { value: compId },
                [torihikisakiName]: { value: compName },
                [mithumoriTotalPriceField]: { value: price }
              }
            }
          )
        );
      }
    } else { // priceがundifindの場合
      let deleteId = existingRecord.$id.value;
      requests.push(
        kintone.api(
          kintone.api.url("/k/v1/record",true),
          "DELETE",
          {
            app: APP_B_ID,
            id: deleteId
          }
        )
      );
    }
  }
});`

そのような仕様はない(あるいはあったとしても公表されてない)とおもいますね

ただし、API同時リクエストは100までという制限自体は存在しており、提示いただいているコードからどれだけリクエストを送っているかはわかりませんが、これに抵触する、とかは可能性としてはあるかも?ですね

どちらにせよ、切り分け方としては一旦ログ仕込むのが良いかなぁと思います。
削除の対象に含めているつもりが含めていなかった、ということもあるかもしれますし、上記制限にかかると429エラーがレスポンスとして返ってきます。
地道ではありますが、ログをどこかに残すようにして、切り分けていくという作業があると確実かなと思います。

2 Likes

このコードだけだとAPIの完了を待っていない気がするので、 app.record.detail.delete.submit で実行しているとAPIが完了する前にページを離脱している可能性もあります。
requests にレスポンスをまとめているので、最後に Promise.all か何かで待ってあげると完了まで待ってくれるとは思います。

経験的に、APIを連続で投げまくるとkintone側のデータベースロックが起こってAPIの実行が遅れるので、複数レコードをまとめてAPIで投げることをお勧めします。

もしくは

こういうのを使うかですね (複数アプリと書いてありますが同じアプリにも通用します)

あとはChromeなどのF12の開発者ツールでHTTPの通信内容を確認できるので、muraさんが仰っているようなエラーが返ってきていないか確認していただくのが良いかと思います。

2 Likes

muraさん、住田知基さん
返信が遅れてしまい申し訳ありません。
ご回答ありがとうございます。
記述したような仕様は現状無いとのことで、知見が増えました。

コンソールにてエラーでは400badrequestでした。
処理の中でここ以外にもapiを使用している部分があるため、リクエスト制限に引っかかっている可能性はありそうです。。。

一応の解決策としたことなのですが、論理削除からの物理削除で逃げました。
更新処理と削除処理はできなくとも、更新処理自体であれば実行される為、カラム「削除フラグ」を追加して、このフラグに1を設定して更新処理。その後、index.showのトリガーでアプリBのレコード群から削除フラグに1が立っているレコードを抽出して、物理削除する。
このやり方であれば、画面の再読み込みは必要ですが、アプリBから7月分のレコードを削除することができました。
Promise.allについては、知識不足で実装がうまくできませんでした。
アドバイスいただいたのに、ごめんなさい。。。

1 Like

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