Railsのroutesのshallowは安易に使わないで欲しい

Ruby on Rails

概要

  • Shallowの説明はRails Guideにあるとおり。
  • example
    • normal: /authors/1/articles/1
    • shallow:
    • /articles/1 (authorのIDはarticleのIDがわかれば自明だから指定しないで良いでしょという理由により)
  • shallowの説明には設計レベルのメリットしか書いていない。
  • 実装レベルの観点が抜けており、実装レベルでは問題がありそうと直感的に思ったので考えをまとめてみた。

メリット

  • 親と子のリソースがある前提で、親のIDは子供のIDから導き出せるから親のIDを指定することを省略できる。

デメリット

  • RESTの思想から外れる
  • railsのroutesで指定するshallowではまったのように、実装レベルでの問題が起きる
  • 実装レベルの話で、子供のEntityの管理ページ一式(Create, Read, Update, Delete)を作成するときに、shallowを使わなければ親の事は気にする必要無いけど、shallowを使う場合は親のIDを子供が持ち回したりしないといけなくなります。
    • 主に、newと、destroyのリダイレクト先。
    • /articles/new?author_id=1 みたいな。pathでこの必須パラメータを表現出来ないので、routes.rbに仕様として落とし込めない。
    • redirect_to [:articles, author_id: < 削除前のauthor_id>] みたいにして変数をわざわざ1個用意してあげないといけない。
  • 上記に付随して、親のIDを使った権限チェックなどを行っている場合は子供側で親の権限もケアしなければいけなくなり、ロールが綺麗に分割出来ない。
    • パラメータインジェクションすることが容易になり、脆弱性を生みやすくなる。
    • shallowを使わなければ親レベルで制御出来るので。
  • pathとディレクトリ構造が異なるのでメンテナンス性が悪くなる。

自分の考え

  • URLは短くなりますが、やっぱり基本的にRESTの思想を優先してURLを設計したほうが良いと強く思いました。
  • これだけ多くのデメリットがあるshallowを使うケースって一体どのようなときだろうか。
  • URLのpathは短くなりますが、弊害が多すぎ。10害あって1利あるぐらい。

以下に、もう少し深掘りした議論が続きます。

コメント