47463


# 課題

例えば、管理者(Administrator)、編集者(Editor)、一般利用者(User) がそれぞれログイン後の専用ページで books
というリソースを扱いたい場合、どのような URL を提供すべきですか？

## 前提条件

  * 管理者かつ編集者の人もおり、それぞれ全く別のUIを提供するのでページの共通化は不可
  * 各ユーザー種別ごとにマイクロサービス化等はせず、単一のアプリケーションで実装する

# 現状案

1つの案は

[code]

    administrators/books
    editors/books
    users/books
    
[/code]

のようにユーザー種別の複数形を用いるパターンですが、リソース名を含めてしまうと URL からはリソースの関係がネストしているように見えてしまう気がします。

あるいは

[code]

    administrator/books
    editor/books
    user/books
    
[/code]

のようにリソースの単数形を用いるパターンも考えましたが、この場合に素直に Controller を作ると User::BooksController
のように、名前空間のモジュール名とModelクラス名が衝突してしまう問題があります。

もう1つの案は

[code]

    administrator_page/books
    editor_page/books
    user_page/books
    
[/code]

のように素直に誰向けのページかを URL で語るパターンですが、あまり見栄えが良くないように感じますし、こういった URL
を提供しているサービスを思い付きません。

以上、よろしくお願いいたします。


CC BY-SA 4.0
2018-08-11T11:24:01.437
47448
2018-08-12T09:58:11.770
29695
question
ruby-on-rails rest url
ユーザー種別ごとに異なるページで同一のリソースを扱う場合のURL設計について


### 結論としては

[code]

    /admin/books   # Administrator 用 namespace admin
    /editor/books  # Editor 用 namespace editor, edit にするか個人的に迷う
    /books         # 一般ユーザーは普通に見る
    
[/code]

### rest とWebサービスの話

いろいろな web service を見ていて思うのは、おそらく、 rest で設計するにあたって次のような思想があると思います。

  1. RESTful な設計が要請するところにより、リソースベースで URL 設計を行うべきである。 collection, その中の単一リソース、リソースに対するもろもろのアクションがこれに該当する。 rails routing においては、 resources, member や collection に対する操作、 nested resources を活用していくと、大体そんな感じになる。
  2. すべてをリソースベースでの整理は難しいというか、どうも、リソース群をグループ化しないとどうも web サービスは整理できない。なので、何のリソース群を表すかを、フォルダみたいな感じでグループ分けしておく。 rails で言うところの namespace

たとえば、 [Rails のルーティング | Rails ガイド](https://railsguides.jp/routing.html)
を見ていると、管理系の操作は、 admin という namespace ので記述しています。 admin というグループの中で、もろもろのリソースをいわゆる
rest な感じで記述していく方式なのだと理解できます。

こういった、グループ的に利用される url 部分は、いかにもな resource
的記述である場合はむしろまれで、カテゴライズとして分かりやすいものが好まれるようだ、と思っています。 (URL
を利用するのは、最終的には人なので、人にとって分かりやすいことが一番重要なのかなぁ、と。)

### モジュールがぶつかる

Ruby
において、クラスの入れ場所としてモジュールやクラスを利用した場合、怖いのは定数(つまりクラスも)参照に、関係ない機能の定数が紛れこむことかな、と思っています。

自分の記憶が正しければ、 ruby の定数参照は、以下のロジックで行われます。

  1. 定数参照している場所の `Module.nesting` のモジュール達
  2. `Class#ancestors` の定数

で、 `Module#nesting` は、以下のように記述すれば、`Admin::BooksController` のみになったはずです。

[code]

    # app/controllers/admin/books_controller.rb
    class Admin::BooksController < Admin::ApplicationController
    end
    
[/code]

と、考えると、たぶんもろものバランスがいいのは、 controller
まわりのモジュール分けは、その他モデルなどのモジュール・クラス状態には引き摺られずに、 URL
としてどう記述するのが綺麗か、にフォーカスしてそれに合わせることなのかな、と思います。

### どう namespace に分けるか

どうやったら利用者に対して分かりやすさを最大化できるかを考えると、

  1. 一番たくさんこのサービスを利用するのはユーザーなので、普通に `/books` を参照したら、それは一般ユーザー用のページを表示させる
  2. 管理者用ページは namespace 分離して、その中でリソースベースで記述する。一般的なのは多分 admin なので、それを利用する。
  3. 編集者は editor か edit というグループが良さそうな気がする。

### 結論

[code]

    /admin/books   # Administrator 用 namespace admin
    /editor/books  # Editor 用 namespace editor, edit にするか個人的に迷う
    /books         # 一般ユーザーは普通に見る
    
[/code]

はどうでしょうか?


CC BY-SA 4.0
2018-08-12T09:50:59.450
47463
2018-08-12T09:58:11.770
2018-08-12T09:58:11.770
754
754
47448
answer