Laravel 7.x HTTPクライアント

イントロダクション

他のWebアプリケーションと連携を取る、送信HTTPリクエストを簡単に作成できるよう、Laravelは小さくて読み書きしやすいGuzzle HTTPクライアントのAPIを提供しています。LaravelのGuzzleラッパーはもっとも繁用されるユースケースと開発者が素晴らしい体験をできることに重点を置いています。

取り掛かる前に、アプリケーションの依存パッケージとしてGuzzleパッケージをインストールする必要があります。Laravelはデフォルトとしてこの依存パッケージを含んでいます。

composer require guzzlehttp/guzzle

リクエスト作成

リクエストを作成するには、getpostputpatchdeleteメソッドを使用します。最初に基本となるGETリクエストをどのように作成するのか見てみましょう。

use Illuminate\Support\Facades\Http;

$response = Http::get('http://test.com');

getメソッドはIlluminate\Http\Client\Responseのインスタンスを返します。これはレスポンスを調べるために使用できるさまざまなメソッドを持っています。

$response->body() : string;
$response->json() : array|mixed;
$response->status() : int;
$response->ok() : bool;
$response->successful() : bool;
$response->failed() : bool;
$response->serverError() : bool;
$response->clientError() : bool;
$response->header($header) : string;
$response->headers() : array;

Illuminate\Http\Client\Responseオブジェクトは、レスポンス上のJSONレスポンスデータへ直接アクセスできるように、PHPのArrayAccessインターフェイスも実装しています。

return Http::get('http://test.com/users/1')['name'];

リクエストデータ

もちろん、POSTPUTPATCHを使用する場合は、リクエストと追加のデータを一緒に送るのが一般的です。そのため、これらのメソッドは第2引数にデータの配列を受け取ります。データはデフォルトでapplication/jsonコンテンツタイプを使用して送信されます。

$response = Http::post('http://test.com/users', [
    'name' => 'Steve',
    'role' => 'Network Administrator',
]);

GETリクエストのクエリパラメータ

GETリクエストの作成時はクエリ文字列をURLに直接追加するか、キー/値ペアの配列を第2引数としてgetメソッドに渡します。

$response = Http::get('http://test.com/users', [
    'name' => 'Taylor',
    'page' => 1,
]);

URLエンコードされたリクエストのフォーム送信

application/x-www-form-urlencodedコンテンツタイプを使用してデータを送信したい場合は、リクエストを作成する前にasFormメソッドを呼び出す必要があります。

$response = Http::asForm()->post('http://test.com/users', [
    'name' => 'Sara',
    'role' => 'Privacy Consultant',
]);

リクエスト本体をそのまま送信する

リクエスト作成時に、リクエストの本体をそのまま指定したい場合は、withBodyメソッドを使います。

$response = Http::withBody(
    base64_encode($photo), 'image/jpeg'
)->post('http://test.com/photo');

マルチパートリクエスト

ファイルをマルチパートリクエストとして送信したい場合は、リクエストを作成する前にattachメソッドを呼び出す必要があります。このメソッドはファイル名と、その内容を引数に受け取ります。オプションとして第3引数に、ファイルのファイル名と想定できる文字列を指定できます。

$response = Http::attach(
    'attachment', file_get_contents('photo.jpg'), 'photo.jpg'
)->post('http://test.com/attachments');

ファイルのコンテンツ内容をそのまま渡す代わりに、ストリームリソースも指定できます。

$photo = fopen('photo.jpg', 'r');

$response = Http::attach(
    'attachment', $photo, 'photo.jpg'
)->post('http://test.com/attachments');

ヘッダ

withHeadersメソッドで、リクエストにヘッダを追加できます。このwithHeadersメソッドは、キー/値ペアの配列を引数に取ります。

$response = Http::withHeaders([
    'X-First' => 'foo',
    'X-Second' => 'bar'
])->post('http://test.com/users', [
    'name' => 'Taylor',
]);

認証

withBasicAuthwithDigestAuthメソッドを使うと、Basic認証やDigest認証に使用する認証データを指定できます。

// Basic認証
$response = Http::withBasicAuth('taylor@laravel.com', 'secret')->post(...);

// Digest認証
$response = Http::withDigestAuth('taylor@laravel.com', 'secret')->post(...);

Bearerトークン

手早くAuthorization bearerトークンをリクエストのヘッダに追加したい場合は、withTokenメソッドを使います。

$response = Http::withToken('token')->post(...);

タイムアウト

timeoutメソッドはレスポンスを待つ最大秒数を指定するために使用します。

$response = Http::timeout(3)->get(...);

指定したタイムアウト時間が過ぎたら、`Illuminate\Http\Client\ConnectionExceptionのインスタンスが投げられます。

リトライ

クライアントかサーバでエラーが発生したときに、HTTPクライアントへそのリクエストを自動的に再試行させたい場合は、retryメソッドを使います。retryメソッドは2つの引数を取ります。試行回数と、次に試みるまでLaravelに待たせるミリ秒です。

$response = Http::retry(3, 100)->post(...);

リクエストに全部失敗したら、Illuminate\Http\Client\RequestExceptionのインスタンスが投げられます。

エラー処理

Guzzleのデフォルト動作と異なり、LaravelのHTTPクライアントラッパーはクライアントの例外を投げたり、サーバからの400500レベルのレスポンスとしてエラーレスポンスを返したりしません。こうしたエラーが発生したかはsuccessfulclientErrorserverErrorメソッドで判定できます。

// ステータスコードが200以上、300より小さいレスポンスであったかを判定
$response->successful();

// ステータスコードが400より大きいかを判定
$response->failed();

// ステータスコードが400レベルのレスポンスであったかを判定
$response->clientError();

// ステータスコードが500レベルのレスポンスであったかを判定
$response->serverError();

例外を投げる

レスポンスインスタンスを受け取り、そのレスポンスがクライアントかサーバエラーであった場合に、Illuminate\Http\Client\RequestExceptionのインスタンスを投げる場合は、throwメソッドを使います。

$response = Http::post(...);

// クライアントかサーバエラーが発生したため例外を投げる
$response->throw();

return $response['user']['id'];

Illuminate\Http\Client\RequestExceptionインスタンスはパブリックの$responseプロパティを持ち、返されたレスポンスを調査できるようになっています。

throwメソッドはエラーが起きていない場合にレスポンスインスタンスを返すため、別の操作を続けて記述できます。

return Http::post(...)->throw()->json();

Guzzleオプション

withOptionsメソッドを使用し、Guzzleリクエストオプションを追加指定できます。withOptionsメソッドはキー/値ペアの配列を引数に取ります。

$response = Http::withOptions([
    'debug' => true,
])->get('http://test.com/users');

テスト

多くのLaravelサービスは簡単に記述的なテストが書ける機能を提供していますが、HTTPラッパーも例外ではありません。Httpファサードのfakeメソッドで、リクエストが作成されるときに、スタブ/ダミーのレスポンスを返すようにHTTPクライアントに支持できます。

レスポンスのFake

たとえば、すべてのリクエストに200ステータスコードを持つ空のレスポンスをHTTPクライアントから返したい場合は、fakeメソッドを引数なしで呼びます。

use Illuminate\Support\Facades\Http;

Http::fake();

$response = Http::post(...);

特定URLのFake

fakeメソッドに配列を渡すこともできます。配列のキーはfakeするURLパターンを表し、値はレスポンスです。*文字はワイルドカードとして使えます。FakeしないURLに対するリクエストは、実際に実行されます。エンドポイントに対するスタブ/fakeを組み立てるために、responseメソッドを使います。

Http::fake([
    // GitHubエンドポイントに対するJSONレスポンスをスタブ
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),

    // Googleエンドポイントに対する文字列レスポンスをスタブ
    'google.com/*' => Http::response('Hello World', 200, ['Headers']),
]);

一致しないURLをすべてスタブするフォールバックURLパターンを指定する場合は、*文字だけを使います。

Http::fake([
    // GitHubエンドポイントに対するJSONレスポンスをスタブ
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),

    // その他すべてのエンドポイントに対して文字列レスポンスをスタブ
    '*' => Http::response('Hello World', 200, ['Headers']),
]);

一連のレスポンスのFake

特定の順番で一連のfakeレスポンスを一つのURLに対して指定する必要がある場合もときどきあります。このレスポンスを組み立てるには、Http::sequenceメソッドを使用します。

Http::fake([
    // GitHubエンドポイントに対して一連のレスポンスをスタブ
    'github.com/*' => Http::sequence()
                            ->push('Hello World', 200)
                            ->push(['foo' => 'bar'], 200)
                            ->pushStatus(404),
]);

一連のレスポンスを全部返し終えると、そのエンドポイントに対する以降のリクエストには例外が投げられます。このとき例外を発生させる代わりに特定のレスポンスを返すように指定したい場合は、whenEmptyメソッドを使用します。

Http::fake([
    // GitHubエンドポイントに対して一連のレスポンスをスタブ
    'github.com/*' => Http::sequence()
                            ->push('Hello World', 200)
                            ->push(['foo' => 'bar'], 200)
                            ->whenEmpty(Http::response()),
]);

順番のあるレスポンスをfakeしたいが、fakeする特定のURLパターンを指定する必要がなければ、Http::fakeSequenceメソッドを使います。

Http::fakeSequence()
        ->push('Hello World', 200)
        ->whenEmpty(Http::response());

コールバックのFake

特定のエンドポイントでどんなレスポンスを返すか決めるために、より複雑なロジックが必要な場合は、fakeメソッドへコールバックを渡してください。このコールバックはIlluminate\Http\Client\Requestのインスタンスを受け取るので、レスポンスインスタンスを返してください。

Http::fake(function ($request) {
    return Http::response('Hello World', 200);
});

レスポンスの調査

レスポンスをfakeしているとまれに、自分のアプリケーションが正しいデータやヘッダを送っていることを確認するため、クライアントが受け取るリクエストを調べたくなります。これを行うには、Http::fakeを呼び出したあとにHttp::assertSentメソッドを呼び出します。

assertSentメソッドはIlluminate\Http\Client\Requestインスタンスを受け取るコールバックを引数に取り、そのリクエストが期待通りであったかを示す論理値をそのコールバックから返します。テストにパスするには、指定した期待に合致する最低一つのリクエストが発送されている必要があります。

Http::fake();

Http::withHeaders([
    'X-First' => 'foo',
])->post('http://test.com/users', [
    'name' => 'Taylor',
    'role' => 'Developer',
]);

Http::assertSent(function ($request) {
    return $request->hasHeader('X-First', 'foo') &&
           $request->url() == 'http://test.com/users' &&
           $request['name'] == 'Taylor' &&
           $request['role'] == 'Developer';
});

必要であればassertNotSentメソッドを用い、指定するリクエストが送信されなかった事をアサートすることもできます。

Http::fake();

Http::post('http://test.com/users', [
    'name' => 'Taylor',
    'role' => 'Developer',
]);

Http::assertNotSent(function (Request $request) {
    return $request->url() === 'http://test.com/posts';
});

もしくは、リクエストがまったく送信されないことをアサートしたい場合には、assertNothingSentメソッドを使用してください。

Http::fake();

Http::assertNothingSent();

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる