Laravel5.2でRESTfulに開発する

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

img001

このコマンドを実行すると以下のようなひな形ができます。

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);
}

img01

 

新規作成
/*-------------------------------------------------------
 * 新規作成
 --------------------------------------------------------*/
public function create()
{
  return view('greeting.create')->with('message','あなたの名前を入力してください。');
}

img02

 

新規保存

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','新規保存の処理完了!');
}

img03

 

表示

一覧からどれか1つクリックするとそのレコードの詳細が表示される画面のことですね。

1つのレコードに項目がたくさんあったら詳細画面は必要ですが、ここでは名前しかカラムがないので省略します。

/*-------------------------------------------------------
 * 表示
 --------------------------------------------------------*/
  public function show($id)
  {
  //
  }

 

編集
/*-------------------------------------------------------
 * 編集
 --------------------------------------------------------*/
public function edit($id)
{
  $data = Greeting::findOrFail($id);
  return view('greeting.edit')->with('message','編集フォーム')->with('data',$data);
}

img04

 

更新
/*-------------------------------------------------------
 * 更新
 --------------------------------------------------------*/
public function update(GreetingRequest $request,$id)
{
  $greeting = Greeting::findOrFail($id);
  $greeting->onamae = $request->input('onamae');
  $greeting->save();
  return redirect('/greeting/')->with('status', '更新処理完了!');
}

img05

 

削除
/*-------------------------------------------------------
 * 削除
 --------------------------------------------------------*/
public function destroy($id)
{
  $greeting = Greeting::findOrFail($id);
  $greeting->delete();
  $data = Greeting::all();
  return redirect('/greeting/')->with('status', '削除処理完了!')->with('data',$data);
}

img06

 

2. Bladeテンプレート

コントローラのメソッドにあわせたビュー名に変更します。

img07

 

一覧表示

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 を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら

>> Twitter をフォローする

 

-基礎知識