2018/10/12
Laravelの勉強を進めていくにつれてよく出てくる単語が "RESTful" という単語です。
読み方は "レストフル" で間違いないかと思います。
RailsではRESTfulを推奨していて、それにそった機能設計が為されているそうです。
Laravelもこの流れにのっているのでしょう。
とりあえずさらっとですが調べてみたのですが難しい。。ずっと逃げ回っていました。
しかしあまりにもLaravelの構築において出現頻度が高いので腰を据えて勉強してみました。
今回はRestfulについての記事です。
RESTfulとは?
RESTとはWEBの設計思想のひとつです。
どのような設計思想か?
あるリソース(ここではDBのレコード)を取得するのか更新するのかは、HTTPのリクエストメソッドとURIに応じて操作をするというものです。
代表的なHTTPメソッドとその定義を見てみます。
メソッド | 役割 |
---|---|
GET | リソースの取得(読み込み) |
POST | リソースの新規作成 |
PUT | 既存リソースの更新 |
DELETE | リソースの削除 |
ここからさらにURIを付け加えたのが以下になります。
※操作対象が記事(Article)の場合
METHOD | URI | ACTION | 操作内容 |
---|---|---|---|
GET | /articles | ArticlesController@index | 一覧表示 |
GET | /articles/create | ArticlesController@create | 新規作成 |
POST | /articles | ArticlesController@store | 新規保存 |
GET | /articles/{article} | ArticlesController@show | 表示 |
GET | /articles/{article}/edit | ArticlesController@edit | 編集 |
PUT/PATCH | /articles/{article} | ArticlesController@update | 更新 |
DELETE | /articles/{article} | ArticlesController@destroy | 削除 |
RESTの概念に基づいて設計されたものをRESTfulと言います。
Laravelでは RESTful にコントローラやルーティングの設定ができるようになっています。
RESTfulなコントローラを作成する
Laravelでは RESTful なControllerのひな形を簡単に作成することができます。
php artisan make:controller ProductController --resource
このコマンドを実行すると以下のようなひな形ができます。
namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Models\Product; class ProductController extends Controller { /** * 検索表示 * * @return \Illuminate\Http\Response */ public function index() { // } /** * 新規作成画面 * * @return \Illuminate\Http\Response */ public function create() { // } /** * DBレコード新規作成 * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { // } /** * 表示画面 * * @param \App\Models\Product $product * @return \Illuminate\Http\Response */ public function show(Product $product) { // } /** * 編集画面 * * @param \App\Models\Product $product * @return \Illuminate\Http\Response */ public function edit(Product $product) { // } /** * DBレコード編集 * * @param \Illuminate\Http\Request $request * @param \App\Models\Product $product * @return \Illuminate\Http\Response */ public function update(Request $request, Product $product) { // } /** * DBレコード削除 * * @param \App\Models\Product $product * @return \Illuminate\Http\Response */ public function destroy(Product $product) { // } }
これらのメソッドはRESTfulのパターンに基づいて命名されています。
このコントローラを "RESTコントローラ" または "Resourceコントローラ" と読んだりします。
ルーティングで Route::Resource を使う
Restfulなコントローラを作成したら次はルーティングですよね。
Laravel5.2ではルーティングの設定で Route::resource という書き方ができるようになりました。
以下の1行だけで全てのパターンのルートを定義することができます。
Route::resource('product', 'ProductController.php');
ちなみに Route::controller という記述は5.2ではなくなりました。(コードではまだ対応しているようです)
実現したいこと
以前作成したコントローラをRESTに基づいたメソッド名に編集します。
また操作対象(greeting)のビューファイルは "greeting" フォルダに入れます。
手順
1. コントローラの編集
またデフォルトで入力画面を表示させていたのですが、一覧表示に変更します。
DBを操作する処理( store / update / destroy )に関してはFlashメッセージを流すことにします。
まずは一覧表示ですね。
一覧表示
新しい順に並ぶように今回少し編集しました。
ビューファイルですが、greetingフォルダを作成してそのフォルダの中にテンプレートファイルをまとめることにします。
greeting/index.blade.phpを呼び出す場合は
view('/greeting.index')
と "."(カンマ) を記述します。 ※"/"(スラッシュ)でないので注意
/*------------------------------------------------------- * 一覧表示 --------------------------------------------------------*/ public function index() { # 新しい順に並べる(今回新しく追加) $data = Greeting::latest('created_at')->get(); return view('greeting.index')->with('message','あいさつした人のリスト')->with('data',$data); }
新規作成
/*------------------------------------------------------- * 新規作成 --------------------------------------------------------*/ public function create() { return view('greeting.create')->with('message','あなたの名前を入力してください。'); }
新規保存
EloquentでDBの保存処理をします。
保存の処理が終わったらTOPにリダイレクトします。
public function store(GreetingRequest $request) { # 新しいレコードの追加 $greeting = new Greeting(); $greeting->onamae = $request->input('onamae'); $greeting->save(); # View表示 $res = "こんにちは!" . $request->input('onamae')."さん!!"; $data = Greeting::latest('created_at')->get(); return redirect('/greeting/')->with('message',$res)->with('data',$data)->with('status','新規保存の処理完了!'); }
表示
一覧からどれか1つクリックするとそのレコードの詳細が表示される画面のことですね。
1つのレコードに項目がたくさんあったら詳細画面は必要ですが、ここでは名前しかカラムがないので省略します。
/*------------------------------------------------------- * 表示 --------------------------------------------------------*/ public function show($id) { // }
編集
/*------------------------------------------------------- * 編集 --------------------------------------------------------*/ public function edit($id) { $data = Greeting::findOrFail($id); return view('greeting.edit')->with('message','編集フォーム')->with('data',$data); }
更新
/*------------------------------------------------------- * 更新 --------------------------------------------------------*/ public function update(GreetingRequest $request,$id) { $greeting = Greeting::findOrFail($id); $greeting->onamae = $request->input('onamae'); $greeting->save(); return redirect('/greeting/')->with('status', '更新処理完了!'); }
削除
/*------------------------------------------------------- * 削除 --------------------------------------------------------*/ public function destroy($id) { $greeting = Greeting::findOrFail($id); $greeting->delete(); $data = Greeting::all(); return redirect('/greeting/')->with('status', '削除処理完了!')->with('data',$data); }
2. Bladeテンプレート
コントローラのメソッドにあわせたビュー名に変更します。
一覧表示
all.blade.php ⇒ index.blade.php
入力画面
greeting.blade.php ⇒ create.blade.php
フォームのアクションは "greeting" のみでOKです。
<form class="form-signin" role="form" method="post" action="{{url('/greeting')}}">
HTTPメソッドが POST なのでGreetingControllerのstoreメソッドにアクセスしてくれます。
編集画面
edit.balde.php は名前はこのままでOKですね。
フォームのアクションは "greeting" のみでOKです。
<form class="form-signin" role="form" method="post" action="{{url('/greeting',$data->id)}}">
HTTPメソッドは隠しメソッドで "PATCH" に指定しているのでGreetingControllerのupdateメソッドにアクセスしてくれます。
3. グローバルメニューの修正
グローバルメニューの箇所を修正します。
: <div id="navbar" class="collapse navbar-collapse"> <?php $var = $_SERVER["REQUEST_URI"]; ?> <?php $link_navi = ""; ?> <?php if(preg_match("/greeting$/", $var)){ $link_navi = "一覧表示"; } ?> <?php if(preg_match("/create/", $var)){ $link_navi = "入力フォーム"; } ?> <ul class="nav navbar-nav"> <li @if($link_navi=='一覧表示')class="active"@endif><a href="/greeting/">一覧表示</a></li> <li @if($link_navi=='入力フォーム')class="active"@endif><a href="/greeting/create">入力フォーム</a></li> </ul> </div> :
4. ルーティングの設定
前回のルーティングの設定はこのように記述していました。
Route::get('/greeting', 'GreetingController@getIndex'); /*index*/ Route::post('/greeting', 'GreetingController@postIndex'); /*index*/ Route::get('greeting/all', 'GreetingController@all'); /*一覧画面*/ Route::get('greeting/edit/{id}', 'GreetingController@edit'); /*編集画面*/ Route::patch('greeting/update/{id}', 'GreetingController@update'); /*編集フォーム⇒UPDATE処理*/ Route::delete('greeting/destroy/{id}', 'GreetingController@destroy'); /*削除*/
Route::resource を使うと上記で記述した内容が1行で済みます。
Route::resource('greeting', 'GreetingController');
URIを確認します。
php artisan route:list
はまったところ
RESTfulとは別にResourceful(リソースフル)という用語もチラチラと見かけます。
で、RESTfulの勉強でこの用語も調べてみました。
しかしResourcefulの意味を調べても中々出てこない。。
どうやらLaravelドキュメントの誤訳のようです。
Resourceful/リソースフル~Laravelのルーティング~
Laravelでは RESTful なControllerのひな形を簡単に作成することができます。
php artisan make:controller ProductController --resource
上記のコマンドで生成されたコントローラはRESTfulコントローラと呼ばれたりResourceコントローラと呼ばれたり。。
憶測ですがResourcefulという用語が生まれたのはこれが原因かもしれませんね。
仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら。