Route::dispatch()で自分のシステム内のAPIを呼び出す(Laravel)

3 min read読了の目安(約2800字

APIを呼び出したいときGuzzleを使うことが多いかと思いますが、
今回はRoute::dispatchで自分のシステム内のAPIを呼ぶ出す方法を試してみたので
早速紹介していきたいと思います!

自分のシステム内のAPI呼び出しを実装する

APIをいくつか準備する

api.phpユーザー作成API会員登録APIを用意します

Route::post('user', 'UserController@store');

Route::post('register', 'RegisterController@register');

UserController@storeを実装する

ユーザー作成API側を実装してみます。

普通のユーザー作成の手順です。

<?php

namespace App\Http\Controllers\Api;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $email = $request->input('email');
	$password = $request->input('password');
        return User::create([['email' => $email, 'password' => bcrypt('password')]]);
    }
}

RegisterController@registerを実装する

Laravelでは標準で認証系のメソッドをたくさん用意してくれていますが、今回はあえて独自実装という仮定で進めます。

このAPIではユーザー作成をして、会員登録完了メール送信を送って、ユーザー情報をフロントに返すという処理をしています。

<?php

namespace App\Http\Controllers\Api;

class RegisterController extends Controller
{
    public function register(Request $request)
    {
        $email = $request->input('email');
	$password = $request->input('password');
	
	// ユーザーを作成する
        $createdUser = User::create([['email' => $email, 'password' => bcrypt('password')]]);
	
	// ユーザーに会員登録完了メール送信を行う
	Mail::to($email)->send(new RegisteredMail();
	
	return ['user' => $createdUser];
    }
}

よく見ると、ユーザーの作成を「ユーザー作成API」と「会員登録API」で全く同じ処理を行っているので、UserController側に処理を寄せたほうが良いですね。

というわけで、RegisterController@registerから、ユーザー作成APIを呼び出してみましょう!

RegisterController@registerで、ユーザー作成のAPIを呼び出す

先程のRegisterController@registerを少し書き換えます。

<?php

namespace App\Http\Controllers\Api;

class RegisterController extends Controller
{
    public function register(Request $request)
    {
        $email = $request->input('email');
	$password = $request->input('password');
	
	// ユーザー作成APIを呼び出す
        $request = Request::create('/api/user', 'POST', ['email' => $email, 'password' => $password]); // 修正
        Route::dispatch($request); // 修正
	
	// ユーザーに会員登録完了メール送信を行う
	Mail::to($email)->send(new RegisteredMail();
	
	return ['user' => $createdUser];
    }
}

これでユーザー作成APIを呼び出すことに成功しました!

補足: Route::dispatch($request)のレスポンスの扱いについて

Route::dispatch($request);

で返ってくる値は、API呼び出したときのResponseと同じです。
なので、返ってくる値を使い固い場合はこのように書けばOKです

$response = Route::dispatch($request);
$responseData = json_decode($response->getContent(), true);

これで返ってくる値の配列が $responseData の中に入ります

注意点があります

例えば、APIのルートでミドルウェアが付いている場合は注意が必要です。

下記のようなルーティングの場合、RegisterController@registerからユーザー作成APIを呼び出す場合に、authミドルウェアが突破できないとリクエストを送ってもミドルウェアで弾かれてしまいます。

Route::middleware('auth')->group(function () {
    Route::post('user', 'UserController@store');
});

Route::post('register', 'RegisterController@register');

おわりに

APIをできるだけ小分けにしてシステム内のAPIを呼び出す方法は、冗長化が防げるのでとてもいい方法だと思います。

しかしミドルウェアなどの理由でこの方法が適さない場合もあるので、注意してください。