🐵

Laravelで外部APIをモック化してみよう

2023/06/24に公開

最初に

laravelで実装してる時や、他の言語で実装していると、どこかで外部のシステムと連携したいときや、0→1で複数サーバーを立てて、もう一つのサーバーレスポンスを使って何かしたい時が必ず訪れる。

そういう時に、外部サーバーがまだ公開されていないからといって実装できません。となるのではなく、外部のサーバーのレスポンスさえ決まっていれば、モックを作って、実際にAPIを叩いたかのような、結果を得ることができる。

サービスプロバイダーを作成

サービスプロバイダーに登録してどこからでも使えるようにしておく。registerメソッドに登録しておくことで、アプリケーション起動時に、APIにアクセスするとMockのレスポンスを返してくれる。また、環境変数によっての処理を自作したサービスプロバイダーに記載することで、複数のMock APIを作成しても、各処理に環境変数の書く必要はなくなる。

<?php

namespace App\Providers;

use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;

class TestResponseServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        if (! App::environment(['local', 'testing'])) {
            return;
        }
        
        Http::fake(function (Request $request) {
            if (Str::is('*/v1/users*', $request->url())) {
                $users = file_get_contents(base_path('.mock/api/user/users.json'));

                return Http::response($users);
            }
	    // 他のMockしたいAPIの返り値を定義
        });
    }
}

プロバイダーを登録

app.phpでサービスプロバイダーを管理してるので、そこに追加する。これをしないと呼び出されないので、要注意

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
        App\Providers\TestResponseServiceProvider::class, // ここに追加

Mock APIを叩くRequestを作成

リクエストクラスの中で外部のAPIを叩く。TestResponseServiceProviderで$responseが決められているので、TestResponseServiceProviderで定義した値が返される

<?php

declare(strict_types=1);

namespace App\Providers;

use Illuminate\Support\Facades\Http;

class MockGetUsersRequest
{
    public function send()
    {
	// ここは実際に決まってるエンドポイント
        $response = Http::get("https://google/app/test/v1/users");
        return $response;
    }
}

上記はエラーハンドリングはどは行ってないが、上記のようにすることで、Mockのデータを返すことができるようになる。

あとは下記でコントロラー側から呼び出せば、外部システムのMockレスポンスや未完成のサーバー側のレスポンスを返すことができるようになる

ControllerでRequestを使う


<?php

declare(strict_types=1);

namespace App\Http\Controllers\User\Home;

use App\Http\Controllers\Controller;
use App\Providers\MockGetUsersRequest;
use Illuminate\Http\JsonResponse;

class HomeController extends Controller
{
    public function index(MockGetUsersRequest $request): JsonResponse
    {
        $user = $request->send();
        return response()->json($user->json());
    }
}

まとめ

  • ServiceProviderを作成して登録すると複数増えてもコード管理が楽

Discussion