読者です 読者をやめる 読者になる 読者になる

Transaction Resource パターン

POST /transactions
 ↓
PUT /transactions/123
 ↓
PUT /transactions/123/committed

「Webを支える技術」p278より引用

実際のシステムでは、より複雑な処理、たとえば複数のリソースにまたがった変更をひとまとまりに扱う、いわゆるトランザクションが必要になるケースもあるでしょう。

主にCollection & Member Resource パターンを用いたトランザクションの実装。

ウィザードなどにも適用可能で、モデルでないリソースになりうる。

http://qa.atmarkit.co.jp/q/2555#answer_15110id:moro さんの回答より引用

やり方はいろいろありますが、データインポートなど複数のリソースに影響を及ぼす、バッチ的な動きをさせたい場合には「トランザクションリソースを作る」という考え方でリソース設計するようにしたところ、いろいろ捗りました。

たとえば今回の例でも「インポート処理: import_job」を作るという風に考えると、ルーティングは

resouces :import_jobs

としておき、

  • GET /import_jobs/new (ImportJobsController#new) でインポート用のフォームなどを表示し、
  • POST /import_jobs (ImportJobsController#create) で実際のインポート処理をはじめるなど、いろいろやりようがあります。

私が実アプリで取り組んだときは、インフラの都合上非同期にインポートジョブを実行させたかったので、createアクションの中でいったん必要な情報をDB(import_jobsテーブル)に保存しました。その後でワーカーに流し、

  • GET /import_jobs/:id で進捗状況や実行結果を表示

という作りにしました。ポイントは『処理の固まり』を作るのもリソース作成としてとらえることです(なんでもかんでもやると妙ちくりんですが)。