🐵
Laravelで外部APIをモック化してみよう
最初に
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