LoginSignup
41

More than 1 year has passed since last update.

Laravel7.x から新しくなった Http クライアントのご紹介

Last updated at Posted at 2020-12-22

Laravel Advent Calendar 2020 - Qiita の 22目 の記事です。
昨日は @nunulk さんのController, UseCase, Service (および Model) の役割分担についての考察の記事でした!
明日は @Lob さんのLaravel on GAE Standard 環境構築の手引きの記事です!

概要

Laravel 6.x 以前はGuzzleHTTPクライアントをそのまま使用する形でしたが、Guzzleのラッパーとして新たにHTTPクライアントが搭載されました。
(Laravel内部ではGuzzleが使用されてます。)

インストール

$ composer require guzzlehttp/guzzle

最新バージョンではデフォルトでGuzzleはインストールされているはず。

ソースコード、ドキュメント

Laravel7

Laravel8

Laravel HTTPクライアントの特徴

  1. チェーンメソッド可能なリクエスト
  2. JSONレスポンスへの簡単なアクセス
  3. シンプルなリクエストを行うための定型的なセットアップが不要
  4. 失敗したリクエストの再試行(リトライ)
  5. 認証ヘッダー(ベーシック、ダイジェスト、ベアラー)の便利メソッド
  6. テストのモック、スタブ

基本的な使い方

use Illuminate\Support\Facades\Http;

// http response
$response = Http::get('https://github.com');
$response->body();

// json response
$response = Http::get('https://api.github.com');
$data = $response->json();

データへのアクセス

json() を介してResponseデータにアクセスできます。

$response = Http::get('https://api.github.com');
$data = $response->json();
$data['current_user_url']; 

Responseオブジェクトにも配列のようにアクセスできます。

$response = Http::get('https://api.github.com');
$response['current_user_url'];

Laravel 6.x 以前の書き方

use GuzzleHttp\Client;

$client = new Client();
$response = $client->request('GET', 'https://api.github.com');
$body = $response->getBody();
$data = json_decode($body, true);
$data['current_user_url'];

色々面倒ですよね...
Laravel 7.x 以降でも上記の書き方は可能です。

エラー処理

Laravel 6.x 以前の書き方

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

try {
    $client = new Client();
    $client->request('GET', 'https://github.com/_abc_123_404');
} catch (RequestException $e) {
    if ($e->hasResponse()) {
        dump($e->getResponse());
    }
}

失敗すると例外が発生するので、try 〜 catch で囲む必要がありました。

use Illuminate\Support\Facades\Http;

$response = Http::get('https://github.com/_abc_123_404');

if ($response->clientError()) {
    dump($response);
}

if 文でリクエスト結果に応じて条件分岐できて便利です。
メソッドもそれぞれ用意されてます。

$response->ok();          // 200 == http status code
$response->successful();  // 200 <= http status code < 300
$response->failed();      // 400 <= http status code
$response->clientError(); // 400 <= http status code < 500
$response->serverError(); // 500 <= http status code

タイムアウト

デフォルトのタイムアウトはとても長いです。(サーバー設定によってまちまちですが)
Laravel HTTPでは、timeout() メソッドで自分で定義できます。

use Illuminate\Support\Facades\Http;
use Illuminate\Http\Client\ConnectionException;

try {
    $response = Http::timeout(5)->get('http://127.0.0.1/api/slow');
} catch (ConnectionException $e) {
    // cURL error 28: Operation timed out after 5001 milliseconds with 0 bytes received (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://127.0.0.1/api/slow
    dump($e->getMessage());
}
  • タイムアウトが発生すると Illuminate\Http\Client\ConnectionException の例外が発生します。
  • timeout() は秒単位で定義できます。

失敗したリクエストの再試行(リトライ)

クライアントもしくはサーバー側のエラーが発生した場合にリトライ処理を行わせます。

// 試行回数3回、待機時間100ミリ秒
$response = Http::retry(3, 100)->post(...);

認証ヘッダー(ベーシック、ダイジェスト、ベアラー)の便利メソッド

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

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

// Bearerトークン
$response = Http::withToken('token')->post(...);

テストのモック、スタブ

use Illuminate\Support\Facades\Http;

Http::fake();

$response = Http::get('https://api.github.com');
$response->json(); // null
$response->status(); // 200

Http::fake(); と1行入れると実際のURLを叩くことなく、200ステータスで空のレスポンスボディを返してくれます。

とても便利ですね!

use Illuminate\Support\Facades\Http;

Http::fake([
    'api.github.com*' => Http::response(['current_user_url' => 'http://example.com']),
]);

$response = Http::get('https://api.github.com');
$response->json(); // ["current_user_url" => "http://example.com"]
$response->status(); // 200

$response = Http::get('https://api.github.com/abc/xyz');
$response->json(); // ["current_user_url" => "http://example.com"]
$response->status(); // 200

このURLを叩いたらこんなレスポンスを返す。
といった定義ももちろん書けます。

APIのテストもしやすくなりますね!

dump, dd ヘルパーメソッド

上記のPRにて、helper, ddヘルパーメソッドが追加されてます。
このヘルパーメソッドを利用すると送信されたリクエストの中身を確認できます。

use Illuminate\Support\Facades\Http;

Http::dump()->get($url);
Http::dd()->post($url);

Laravel 8.31.0 以降に利用できます。

詳しくは...

公式ドキュメントが丁寧にまとめられているので、こちらをご参照ください。

所感

Laravel7.xが出てからだいぶ経ちましたが、Httpクライアントを使う機会がなく記事にまとめることができてませんでした。
この機会にまとめることができてよかったです。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41