Laravelでは、ウェブ開発の経験値を問わず、簡単にAPIを利用することができます。LaravelのHTTPクライアントは、PHPのGuzzle HTTPクライアントをベースに構築されており、スムーズにHTTPリクエストを送信可能です。主な機能には、認証、ルーティング、効果的なオブジェクトリレーショナルマッピング(ORM)があります。

この記事では、LaravelのHTTPクライアントを使用して、リクエストの作成、レスポンスのデバッグ、ミドルウェアとマクロの作成方法などを見ていきます。

LaravelのHTTPクライアントを使いAPIを利用する

Guzzleは、PHP用のシンプルなHTTPクライアントです。GETPOSTPUTDELETEなどの様々なフォームリクエストに対応し、ストリーミング機能やマルチパートリクエスト機能もあります。Guzzle HTTPクライアントを使用すると、サーバーに同期および非同期リクエストを送信できます。さらに、クライアントの動作をカスタマイズするミドルウェアも付属します。

先に触れた通り、LaravelのHTTPクライアントは、Guzzleをベースに構築されたラッパーですが、失敗したリクエストの再試行サポートや、JSONデータ用のヘルパー関数などの機能が追加されています。LaravelのHTTPクライアントのほとんどの機能はGuzzleと共通しています。

前提条件

今回ご紹介するLaravelのHTTPクライアントの活用方法には、以下のソフトウェアやスキルが必要になります。

  • LaravelPHPAPIに関する基本的な知識
  • PHPとComposerのインストール
  • Postman

リクエスト方法

HTTPクライアントを使用したリクエスト方法を理解するには、ReqResのような、多くのホスティング済みAPIを活用できます。

まず、アプリケーション作成時に含まれている、HTTPパッケージをインポートします。App/Http/Controllers/UserController.phpファイル内に以下のコードを追加してください。use文はファイルの先頭に、return文はindex関数内に追加します。

use Illuminate\Support\Facades\Http;
return Http::get("https://reqres.in/api/users?page=2");

注意)複雑なユースケースでは、withHeadersメソッドを使用してヘッダー付きリクエストを送信できます。

同じファイル内に、以下のコードを使用してpostメソッドを作成します。

function post()
{
    $response = Http::withHeaders([
        'Content-Type' => 'application/json',
    ])->post('https://reqres.in/api/users', [
        'name' => 'morpheus',
        'job' => 'leader',
    ]);
    return $response;
}

そしてroutes/web.phpファイル内にルートを追加します。

Route::get('post',[UserController::class,'post']);

これで、Postmanを使用してこのルートをテストできます。Postmanを開き、URLを「http://127.0.0.1:8000/post」、リクエストのタイプをGETとして追加します。「Send」をクリックすると、以下のレスポンスが表示されます。

Postmanを使用したリクエスト
Postmanを使用したリクエスト

並行リクエスト

並行リクエストは同じ期間内に多くのデータを取得できるため、パフォーマンスが大幅に向上します。LaravelのHTTPクライアントで同時リクエストを実行するには、poolメソッドを使用します。

App/Http/Controllers/UserController.php内に、以下のコードを追加します。

use Illuminate\Http\Client\Pool;
function concurrent()
{
    $responses = Http::pool(fn (Pool $pool) => [
        $pool->get('https://reqres.in/api/users?page=2'),
        $pool->get('https://reqres.in/api/users/2'),
        $pool->get('https://reqres.in/api/users?page=2'),
    ]);

    return $responses[0]->ok() &&
        $responses[1]->ok() &&
        $responses[2]->ok();
}

次に、routes/web.phpファイル内にサポートルートを追加します。

Route::get('concurrent',[UserController::class,'concurrent']);

The browser gives the following response when the route is visited:

並行リクエスト
並行リクエスト

リクエストマクロ

リクエストマクロは、一般的なAPIパスと通信する際に便利です。

マクロを作成するには、以下のコードを使用して、app/Http/Providers/AppServiceProvider.phpファイルのbootメソッド内でマクロを定義します。

use Illuminate\Support\Facades\Http;
Http::macro('reqres', function () {
    return Http::baseUrl('https://reqres.in/api');
});

注意)ファイルの最初にuse文を追加してください。

UserControllerの内部でマクロを使用します。

function macro()
{
    $response = Http::reqres()->get('/users?page=2');
    return $response;
}

見て分かるようにマクロを作成したため、再度完全なURLを指定する必要はありません。

最後に、以下のコードを使用してroutes/web.phpファイルにルートを追加します。

Route::get('macro',[UserController::class,'macro']);
マクロリクエスト
マクロリクエスト

レスポンスのデコード方法

レスポンスをデコードし、APIリクエストが成功したことを確認するには、クライアント内のstatusメソッドを使用します。このメソッドは、サーバーから送信されたステータスコードを取得、表示します。

これをテストするには、App/Http/Controllers/UserController.phpファイル内の以前のマクロコードを以下のコードで置き換えます。

function macro()
{
    $response = Http::reqres()->get('/users?page=2');
    return $response->status();
}

ステータスコード200は、リクエストが成功したことを意味します。

成功したレスポンスのデコード
成功したレスポンスのデコード

JSON APIのテスト方法

Laravelには、JSON APIとそのレスポンスをテストできる複数のヘルパー関数があり、jsongetJsonpostJsonputJsonpatchJsondeleteJsonなどがその一例です。

テストをより良く理解するため、usersルートのGETのテストシナリオを作成します。Laravelアプリケーションを立ち上げると、「Example Test」が自動で作成されます。tests/Feature/ExampleTest.phpファイルの既存のコードを以下のように置き換えます。

<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function test_example()
    {
        $response = $this->getJson('/users');

        $response->assertStatus(200);
    }
}

追加したコードは、usersルートでJSONデータを取得し、ステータスコードが200かどうかをチェックします。

テストコードを追加したら、ターミナルで以下のコマンドを実行してテストを行います。

./vendor/bin/phpunit

テストが完了すると以下のように、2つのテストを実行し、どちらも成功したことを伝えるメッセージが表示されます。

JSON APIのテスト
JSON APIのテスト

同様に、異なるタイプのリクエストをチェックし、他のヘルパーメソッドを利用して、より洗練されたテストを実行できます。

イベントの処理方法

LaravelにはHTTPリクエストを処理する際に発生する3つのイベントがあります。

  • RequestSending:リクエストが送信される前
  • ResponseReceived::レスポンスを受信した時
  • ConnectionFailed:レスポンスの受信に失敗した時

3つのイベントはすべて、Illuminate\Http\ClientRequestインスタンスを検査する$requestプロパティを含み、ResponseReceivedには更に$responseプロパティがあります。これらは特に、イベント後にアクションを実行する際に便利です。例えば、成功のレスポンスを取得した後に、メールを送信できます。

イベントとリスナーを作成するには、app/Providers/EventServiceProvider.phpファイルに移動して、listen配列を以下のコードで置き換えます。

protected $listen = [
    Registered::class => [
        SendEmailVerificationNotification::class,
    ],
    'Illuminate\Http\Client\Events\ResponseReceived' => [
        'App\Listeners\LogResponseReceived',
    ],
];

次に、ターミナルで以下のコマンドを実行します。

php artisan event:generate

上のコマンドは、app/Listeners/LogResponseReceived.phpリスナーを作成します。ファイル内のコードを以下のコードで置き換えてください。

<?php
namespace App\Listeners;
use Illuminate\Http\Client\Events\ResponseReceived;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
class LogResponseReceived
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct(Request $request, Response $response)
    {
        Log::channel('stderr')->info($response->status());
    }

    /**
     * Handle the event.
     *
     * @param  \Illuminate\Http\Client\Events\ResponseReceived  $event
     * @return void
     */
    public function handle(ResponseReceived $event)
    {
        
    }
}

ステータスコードの情報がターミナルに表示されます。

ターミナルログに表示されたステータスコード
ターミナルログに表示されたステータスコード

 

まとめ

企業にとっても、個人の開発者にとっても、ウェブサイトやウェブアプリケーションの成功の鍵はAPIにあります。しかしAPIの使用は、時に一筋縄ではいかないことがあります。

多くのフレームワークライブラリがこのプロセスの簡素化を進めていますが、シンプルさと使いやすさの観点から、Laravelは他を圧倒しています。Laravel組み込みのHTTPクライアントは、簡単なAPI呼び出し、並行呼び出し、APIマクロ、JSONベースAPI用のヘルパーメソッドなどに役立ちます。

Steve Bonisteel Kinsta

Kinstaのテクニカルエディター。救急車や消防車を追いかける記者としてキャリアをスタート。1990年代後半からインターネット関連の技術情報を担当している。