フロントエンドアプリで 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/:id な POST を作っているかも?でもそれって 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でも良いのかも。
- Angular 公式のチュートリアルでは
- 照会 : URL を
/users/show/:idとするか/users/:idとするか- Rails Scaffold や REST API の URL 設計だと後者なのだが、それは HTTP メソッドで GET を指定しているから区別が付きやすいのであって、SPA のルーティングの中だと区別が付きにくい気がする。だから URL に
show/を含めるようにしたが、微妙か?照会に関しては後者にしてもいいのかも。
- Rails Scaffold や REST API の URL 設計だと後者なのだが、それは HTTP メソッドで GET を指定しているから区別が付きやすいのであって、SPA のルーティングの中だと区別が付きにくい気がする。だから URL に
- 登録 :
New・Create・Register(Registration)・Addあたりの単語のどれを使うと、コンポーネント名としてしっくりくるか- URL に関しては
/users/newで良いと思うのだが、UserNewComponentがどうかなーと思っている。UserCreateComponentだと、そのコンポーネントを呼んだ時にユーザを生成しちゃいそうな気がするし、UserRegisterComponentやUserAddComponentは動詞なのが違和感。
- URL に関しては
- 更新 : URL を
/users/edit/:idとするか/users/:id/editとするか- Rails Scaffold の場合は後者だが、Angular のルーティングで
:id/editというルーティングを作ると「ルートパラメータ」として:idが渡せないのでedit/:idとした。users/1/editのように URL 文字列を作ってしまえば遷移はできるものの、ルートパラメータとして指定したいので…。
- Rails Scaffold の場合は後者だが、Angular のルーティングで
Rails Scaffold で違和感がないのに、Angular コンポーネントにすると移植しづらいのは、オブジェクト指向で考えた時に、動詞と名詞を変換しないといけないからだろう。Rails の場合は UsersController#show (User を Show する) というように 「Show」という動詞が使えるが、クラス名・コンポーネント名にしようとすると、UserShowComponent もしくは ShowUserComponent というように、落ち着きが悪い。そこで UserDetailComponent というように、「Detail」という名詞を使うようにしたのだが、この変換がしっくりこない箇所がある。特に登録…。
皆様はどうしていますか?ご意見ください。
参考文献
ココまでの内容を考える際に参考にした文献。
- How to structure CRUD routes correctly in Angular projects? - Stack Overflow …
/list・/create - Build a Basic CRUD App with Angular 5.0 and Spring Boot 2.0 | Okta Developer …
/car-list・/car-add・/car-edit(Add と Edit は両方CarEditComponentで賄う) - Using Route Parameters · Rangle.io : Angular 2 Training …
/details(複数形)