Microsoft Graph Event Resource の transactionId プロパティ

2020 年 9 月の更新で、Microsoft Graph の Event Resource に transactionId というプロパティが追加されました。これは、ネットワークの品質が悪い環境などで新しい予定を何度も作ってしまうことを防ぐのに使えるプロパティです。

まずはじめに、予定を作る際に以下のように transactionId を指定してリクエストを送信します。transactionId は何でもよいですが、ここでは意味を持たないランダムな値として GUID を使いました。

POST https://graph.microsoft.com/v1.0/me/events
{
    "attendees": [],
    "body": {
        "content": "test",
        "contentType": "html"
    },
    "end": {
        "dateTime": "2020-10-06T13:30:00",
        "timeZone": "Tokyo Standard Time"
    },
    "isAllDay": false,
    "location": {
        "displayName": ""
    },
    "recurrence": null,
    "start": {
        "dateTime": "2020-10-06T13:00:00",
        "timeZone": "Tokyo Standard Time"
    },
    "subject": "transactionId test",
    "transactionId": "eb739cec-0652-41ee-b169-22102aa1570b"
}

実行すると 201 のレスポンスが返されて予定が作成されます。作成された予定の transactionId にはリクエストに指定した値が設定されています。

ここでさらにもう一度まったく同じリクエストを実行すると、レスポンスとしては 201 が返ってきますが、実際には新しい予定は作成されません。同じ内容の同じ transactionId を持つ予定が既に存在しているためです。

例えば 1 回目の POST の際に予定が作成されたにもかかわらずレスポンスを受信できなかったとします。アプリ側は正常に予定が作られたかわからないので、多く場合はここでリトライ処理としてもう一度 POST のリクエストを送信すると思います。2 回目の POST では、同じ内容の同じ transactionId の予定が既に存在しているので、重複して予定が作成されることはありません。それでもアプリには 201 のレスポンスが返され、アプリ側も正常に予定が作られたと判断することができます。

なおしばらく待てば同じ transactionId を使いまわすこともできますが、短時間のうちに内容の違う別の予定の作成時に transactionId を使いまわすようなことをすると、400 のレスポンスとともに以下のエラーが返されます。

{
  "error": {
    "code": "ErrorDuplicateTransactionId",
    "message": "Your request can't be completed. The TransactionId specified in the request has already been used to create a different event.",
    "innerError": {
      "date": "2020-10-05T13:31:29",
      "request-id": "f8cb3197-cf95-4465-8ae5-acbc40c8ac8b",
      "client-request-id": "f8cb3197-cf95-4465-8ae5-acbc40c8ac8b"
    }
  }
}