Laravelでルーティングを書く方法について、書き方や概念などをまとめてみました。
Laravelのバージョン11で検証しました。
※後述していますが、Laravel7以前では書き方がちょっと違います。
Laravelのルーティングとは?
Laravelでルーティングは特定のURLにアクセスされたときに「どのような処理をするのか」といったことを定義します。
例えば、https://xxx
といったサイトがあった場合を考えます。
https://xxx/login
にアクセスされた場合は、ログイン画面を表示するとします。
/login
にアクセスするときに行う処理を書く場合、下記のようにルーティングをroutes/web.php
に記載します。
Route::get('/login', function() {
return view("login");
});
第1引数にURLを記載して、第2引数に行う処理を書きます。
今回はクロージャでビューを返すようにしましたが、下記のようにコントローラーを指定することもできます。
use App\Http\Controllers\LoginController;
Route::get('/login', [LoginController::class, 'index']);
コントローラーを指定して、カンマで区切ってメソッドを指定しました。
これで「/login
にアクセスされると、LoginControllerのindexメソッドの処理をする」という意味になります。
このようにURLを指定したり、フォームからデータ送信する際に「処理先(ルート)」を決めるのがLaravelのルーティングです。
Laravelのルーティングには、2つのファイルが存在します。
1. Webサイトの画面からのアクセスを定義するファイル(routes/web.php
)
2. Consoleコマンドの定義・スケジュールするファイル(routes/console.php
)
通常はroutes/web.php
を使用して、Webブラウザからのアクセスを定義します。
routes/console.php
にはコマンドを定義したり、スケジュールすることができます。
api.phpは?
Laravel11から初期状態でroutes/api.php
がなくなりました。
SPA(シングルページアプリケーション)などで、APIを使いたい時には、下記のコマンドでAPIルートを追加することができます。
$ php artisan install:api
実行することで、laravel/sanctum
のライブラリも追加されます。
ルーティングを書く
画面からのアクセスをルーティングする具体的な方法を確認します。
コントローラーへのルーティング
基本的なコントローラーへのルーティングは、下記のようになります。
Route::get('/test-welcome', [TestController::class, 'welcome']);
`https://xxx/test-welcome`にアクセスされると、`TestController`の`welcome`メソッドで処理されます。
下記のように、スラッシュ(‘/’)で定義して、階層を深くすることも可能です。
Route::get('/test/welcome', [TestController::class, 'welcome']);
第2引数は同じように書いています。
`https://xxx/test/welcome`にアクセスされると、同じように`TestController`の`welcome`メソッドが使われます。
クロージャーで処理を記載する
コントローラーで処理するほどのボリュームがない場合は、第2引数にクロージャーを書いて、定義することが可能です。
とりあえずモックを作成して、画面だけ表示しておきたい場合などに使うことがあります。
Route::get('/test/welcome', function() {
return view("welcome");
});
`https://xxx/test-welcome`にアクセスされると、`welcome`ビューを表示します。
名前付きルーティング
名前付きルーティングは、作成したルートに名前をつけて使いやすくすることです。
例えば、先ほど定義したルートは、下記のようにnameメソッドを使用することができます。
Route::get('/test/welcome', [TestController::class, 'welcome'])->name('test.welcome');
このように定義することで、このルート名がtest.welcome
になります。
そして、route
ヘルパーなどから簡単にルートが指定できます。
例えば、リダイレクトする場合は下記のように記述することができます。
return redirect()->route('test.welcome');
viewのフォームから送信する場合は、route
ヘルパーを使用して下記のようにaction
を定義することができます。
<form action="{{ route('test.welcome') }}" method="get">
<!-- フォームの内容 -->
</form>
name
メソッドを使って、名前をつけておくことにデメリットはありません。
ルートを作ったらとりあえず付けておくと良いです。
groupルーティング
ルーティングをグループ化することができます。
URLの階層が深くなる場合は、一括して定義することが可能です。
例えば、下記のように定義することができます。
Route::group(['prefix' => 'test'], function(){
Route::get('hoge', function() {
echo "hoge";
});
Route::get('fuga', function() {
echo "fuga";
});
});
Route
のgroup
メソッドを使って、/test
以下のURLを一括で定義しています。
これによって/test
配下がまとめられます。
/test/hoge
にアクセスすると、”hoge”が出力されます。
/test/fuga
にアクセスすると、”fuga”が出力されます。
ここではURLをまとめる方法をご紹介しました。
他にもグループのURLに一括してミドルウェアを適用したり、名前付きルーティングを一括でまとめることもできます。
ルーティングのミドルウェアとは?
groupのルーティングでミドルウェアという言葉が出てきました。
LaravelのミドルウェアはURLにアクセスしたら、「処理をする前」や「処理をした後」に何らかの処理を挟むことができる機能です。
例えば「URLにアクセスしたら、ログを出力する」ような機能です。
それぞれのコントローラーでログを出力するよりも、一括して処理したほうが楽ですね。
このようにルートにアクセスしたときに、「共通した処理を行いたい」場合にミドルウェアを使います。
このミドルウェアをルートに適用することができます。
例えば、先ほどのログ出力機能がlogger
という名前で作成されていた場合は、下記のようにミドルウェアを定義できます。
Route::group(['middleware' => Logger::class], function () {
Route::get('/test/hoge', function() {
echo "hoge";
});
Route::get('/test/fuga', function() {
echo "fuga";
});
});
/test/hoge
と/test/fuga
、それぞれのルートにアクセスされたときにログが出るようになります。
ルーティングするときのHTTPのメソッド
これまでRoute
のget
メソッドで説明してきましたが、これは「HTTPでGET
アクセスされるURL」を定義するときに使います。
他にもHTTPのリクエストメソッドによって、書き方が違うので確認しましょう。
GETメソッド
下記のように書くと、GETメソッドでアクセスできます。
URLを直接ブラウザに入れてアクセスする場合や、HTMLのaタグでリンクするときによく使います。
Route::get('/test/hoge', [TestController::class, 'hoge'])->name('test.hoge');
POSTメソッド
下記のように書くと、POSTメソッドでアクセスできます。
Route::post('/test/hoge', [TestController::class, 'hoge'])->name('test.hoge');
GETと同じ名前のルート(URL)でも、別メソッドなら一緒に定義することができます。
よく使われるのは、フォームから保存する値を送信するときです。
GETで送信すると、URLに出てきてしまうので、ユーザーに登録してもらう内容などはこちらを使用します。
気をつけないといけないのは、使用する場合はフォームに@csrf
を入れておく必要があります。(csrf対策のため)
POSTするフォームは下記のように記載します。
<form action="{{ route('test.hoge') }}" method="POST">
@csrf
<!-- フォームの項目を記載 --->
<input type="submit" value="submit" />
</form>
上記のように@csrf
を忘れないようにしましょう。
このように定義しておくと、@csrf
はフォームの中で下記のようにhidden
項目として展開されます。
<input type="hidden" name="_token" value="nWAJhRxOzlNBJhVaEpMrHU7YtgQTgKka7Eh3TR9J">
この項目がない場合は、LaravelでPOSTするとエラーになるので、気を付けましょう。
PUTメソッド
PUTメソッドを使用するときは、このように書きます。
Route::put('/test/hoge', [TestController::class, 'hoge'])->name('test.hoge');
PUTメソッドは、登録されているデータを更新する場合に使用されます。
使用する場合は@csrf
に加えて、メソッドの定義が必要です。
<form action="{{ route('test.hoge') }}" method="POST">
@method("PUT")
@csrf
<!-- フォームの項目を記載 --->
<input type="submit" value="submit" />
</form>
上記のように@method
を使ってメソッド定義が必要です。
これはHTMLのフォームがPUTメソッドに対応していないためです。
定義したメソッドは下記のようにHTMLで展開されます。
<input type="hidden" name="_method" value="PUT">
DELETEメソッド
DELETEメソッドを使う場合も、ルーティングでは下記のようにメソッドを変えるだけです。
DELETEメソッドは、データを削除する場合に使用されます。
Route::delete('/test/hoge', [TestController::class, 'hoge'])->name('test.hoge');
PUTと同様に@method
を使用して、メソッド定義が必要です。
<form action="{{ route('test.hoge') }}" method="POST">
@method("DELETE")
@csrf
<!-- フォームの項目を記載 --->
<input type="submit" value="submit" />
</form>
ルートにパラメータを含めるには?
作成したルートにパラメータを含める方法を確認します。
URLパラメータをひとつ渡す
URLにパラメータを含めるには下記のように記載します。
Route::get('/test/hoge/{id}', [TestController::class, 'hoge']);
アクセスするときには/test/hoge/1
のようなURLからアクセスできます。
取得するコントローラー側で、このように取得します。
public function hoge(int $id) {
echo "id is {$id}";
}
URLパラメータを複数渡す
複数定義したい場合は、下記のように渡すことが可能です。
Route::get('/test/hoge/{id}/name/{name}', [TestController::class, 'hoge']);
アクセスするときには/test/hoge/1/name/taro
のようなURLからアクセスできます。
取得するコントローラーでは、引数を増やすと受け取れます。
public function hoge(int $id, string $name) {
echo "id is {$id}<br>";
echo "id is {$name}<br>";
}
APIルーティングについて
apiを使用したルーティングを定義する場合は、routes/api.php
に書きます。
routes/web.php
に書くのと同じように書けます。
上記で書いたように、別途コマンドでAPIルートを作ってSanctumを導入する必要があります。
Route::get('/hello', function () {
return response()->json(['text' => 'hello, world']);
});
気をつけるところですが
上記のように書いた場合、標準のままだと/api/hello
というように/api
から始まるURLになります。
Laravelのバージョン7以前での書き方
Laravelのバージョン8から、標準のルーティングの書き方が変わりました。
7以前では基本的な書き方として、処理先のコントローラーを指定するときは、下記のように書いていましたが…
Route::get('/test/welcome', 'TestController@welcome');
Laravel8から、このようにコントローラーとメソッドを分けて書くようになっています。
Route::get('/test/welcome', [TestController::class, 'welcome']);
コメント