Murga

個人的に言いたいコト・主張・気持ち。

フロントエンドアプリで CRUD する時の命名規則に迷っている

Rails の Scaffold 機能みたいな要領で、SPA なライブラリの中で、あるリソースの CRUD を行う画面を作りたいとする。その時のクラス名、ディレクトリ構成、メソッド名などのベストプラクティスがイマイチ見つからないので、自分なりに検討してみた。

Rails Scaffold のおさらい

Rails で Scaffolding した時に生成されるリソースは以下のようになる。

Verb URI Pattern Action 備考
GET /users Index 一覧表示
POST /users Create 新規登録 (ID 自動採番)
GET /users/new New 新規登録画面を開く
GET /users/:id Show 照会画面・1件取得
GET /users/:id/edit Edit 編集画面を開く
PUT /users/:id Update 全体更新
PATCH /users/:id Update 一部更新
DELETE /users/:id Destroy 削除

読み方は、左から、HTTP メソッド「Verb」で「URI Pattern」にアクセスした時、UsersController の「Action」メソッドを実行する、という形。

例えば、新規登録画面を開くのは /users/new という URL で、UsersController#new メソッドで登録画面の初期表示用の処理を行う。その登録画面から「登録」ボタンを押した時は、/users という URL に POST 通信して、UsersController#create メソッドで新規登録処理を行う、といった形だ。

フロントエンドアプリの場合

フロントエンドアプリ、ココでは主に Angular を想定しているが、React や Vue.js でも変わらないだろう。要するに API サーバは別にある、SPA なフロントエンドアプリの場合だ。

この場合、API サーバ側の URL は一旦考えなくて良い。RESTful な API 設計がなされていれば、大体以下のような URL パターンになっているはずだからだ。

Verb URI Pattern 備考
GET /users 一覧取得
POST /users 新規登録 (ID 自動採番)
GET /users/:id 1件取得
PUT /users/:id 全体更新
PATCH /users/:id 一部更新
DELETE /users/:id 削除

コレに加えて、もしかしたら /users/:idPOST を作っているかも?でもそれって PUT と変わらないはずだから基本はこうかな?

で、コレとは別に、フロントエンドアプリはどういう構成にしようか、というのが今回の話。

俺が考えた構成

先に「ぼくのかんがえたさいきょうの構成」みたいなものを紹介する。自分が一人で作る時は以下のような構成にしている。Angular 寄りな人間なので、Angular 的なクラスも書いているが、他の SPA フレームワークでも通じると思う。

app/
└ users/
   ├ users.module.ts
   ├ users-routing.module.ts
   ├ user-list/
   │ └ user-list.component.ts
   ├ user-detail/
   ├ user-new/
   └ user-edit/

ルーティングの構成は以下のとおり。

URL コンポーネント名 (クラス名) ファイルパス
/users/index UserListComponent ./users/user-list/user-list.component.ts
/users/show/:id UserDetailComponent ./users/user-detail/user-detail.component.ts
/users/new UserNewComponent ./users/user-new/user-new.component.ts
/users/edit/:id UserEditComponent ./users/user-edit/user-edit.component.ts

削除に関しては、一覧表示 (Index・List) か照会 (Show・Detail)、編集 (Edit) 画面のいずれかから実行すれば良いかと思うので、「削除画面」は用意していない。

基本方針

  • リソースのまとまりを表現するディレクトリは複数形:この場合だと ./users/ ディレクトリは複数形。
  • 各画面を構成するコンポーネント名では単数形:user-detail のように、扱うデータが1つであることを示す。
    • いきなり「IndexComponent」「EditComponent」などと作ってしまうと、「Users」以外の (例えば「Products」など他の) リソースに対する CRUD を作った時に同名のクラスが登場して区別しづらくなるから、単数形のリソース名を接頭辞のように付与している。
  • URL については Rails Scaffold や REST API 設計の真似。

迷っていること

ココまで考えたものの、まだ色々と迷っている。

  • 一覧:URL を /users のみとするか /users/index とするか
    • /users/users/index にリダイレクトすることにしていたりするのだが、最初から /users だけでも良いだろうか。
  • 一覧:コンポーネント名を UserListComponent とするか UsersComponent とするか
    • Angular 公式のチュートリアルでは hero-list.component.ts というクラスが出てくるので、UserListComponent としたが、複数リソースを扱うことを表現するなら、単語を複数形にして UsersComponent でも良いのかも。
  • 照会:URL を /users/show/:id とするか /users/:id とするか
    • Rails Scaffold や REST API の URL 設計だと後者なのだが、それは HTTP メソッドで GET を指定しているから区別が付きやすいのであって、SPA のルーティングの中だと区別が付きにくい気がする。だから URL に show/ を含めるようにしたが、微妙か?照会に関しては後者にしてもいいのかも。
  • 登録:NewCreateRegister (Registration)・Add あたりの単語のどれを使うと、コンポーネント名としてしっくりくるか
    • URL に関しては /users/new で良いと思うのだが、UserNewComponent がどうかなーと思っている。UserCreateComponent だと、そのコンポーネントを呼んだ時にユーザを生成しちゃいそうな気がするし、UserRegisterComponentUserAddComponent は動詞なのが違和感。
  • 更新:URL を /users/edit/:id とするか /users/:id/edit とするか
    • Rails Scaffold の場合は後者だが、Angular のルーティングで :id/edit というルーティングを作ると「ルートパラメータ」として :id が渡せないので edit/:id とした。users/1/edit のように URL 文字列を作ってしまえば遷移はできるものの、ルートパラメータとして指定したいので…。

Rails Scaffold で違和感がないのに、Angular コンポーネントにすると移植しづらいのは、オブジェクト指向で考えた時に、動詞と名詞を変換しないといけないからだろう。Rails の場合は UsersController#show (User を Show する) というように 「Show」という動詞が使えるが、クラス名・コンポーネント名にしようとすると、UserShowComponent もしくは ShowUserComponent というように、落ち着きが悪い。そこで UserDetailComponent というように、「Detail」という名詞を使うようにしたのだが、この変換がしっくりこない箇所がある。特に登録…。

皆様はどうしていますか?ご意見ください。

参考文献

ココまでの内容を考える際に参考にした文献。

Ruby on Rails 5の上手な使い方 現場のエンジニアが教えるRailsアプリケーション開発の実践手法 (Web Engineer's Books)

Ruby on Rails 5の上手な使い方 現場のエンジニアが教えるRailsアプリケーション開発の実践手法 (Web Engineer's Books)

  • 作者: 太田智彬,寺下翔太,手塚亮,宗像亜由美,株式会社リクルートテクノロジーズ
  • 出版社/メーカー: 翔泳社
  • 発売日: 2018/01/24
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る