makotan _at_ gmail dot com

‎REST APIでロールバック的な処理を考えてみた

REST APIで困るのが複数のAPIを呼び出したときのロールバック処理
何がどう困るかというと、API-1,API-2,API-3って更新処理をするAPIがあって、API-3でエラーが出たときにAPI-1とAPI-2のロールバック処理は行えない!

これまではどうやってたか

API-1とAPI-2の呼び出し前の状態を保持して、API-3がエラーになるとAPI-1とAPI-2を呼び出し前に更新する
この問題は、呼び出し前の状態を意識的に保持する必要があるのと、最初の更新方法(追加・更新・削除)によってその逆を実行する必要がある
しかもAPI-1とAPI-2の呼び出しが両方成功しないとロールバックができたことにもならない
設計と実装に結構な負担を強いる方法なのでだいぶ辛かった(実体験)

ロールバックの実現方法

APIの呼び出し時にヘッダにTransaction-ID(以後TID)を呼び出し側が指定する
TIDが指定されてる変更系の呼び出しでは必ず呼び出し前の状態に戻せるような情報を保持する
あと、安全なロールバック手段も一緒に。
一定時間(TID指定とペアで指定することもある)過ぎたTIDに紐づく情報は破棄する(Transactionが成功したものとみなす)
呼び出し元のAPIロールバックすべき状況と判断すると、rollbackにTIDを渡して呼び出すとAPI呼び出し前の処理が無かったことになる

この方法のメリット

呼び出し元がロールバック方法をいちいち検討しなくていいので全体の設計と実装は相当楽になる
呼び出し先のAPIロールバックを任意に実装できるので適切なロールバックが可能になる
呼び出しの経路全てで同じTIDを使用すると情報をトレースできる

この方法のデメリット

呼び出し先のAPIの負担は確実に上がる(ロールバック実現についてAPI別に検討と実装が必要)
サーバの障害などでロールバックが呼び出せなかったときの対処は呼び出し元に必要
呼び出し先のAPIロールバックを受け入れてないとやっぱり面倒なまま