Laravel - Digging Deeper - HTTP Client

# 前言

學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。




# Introduction

Laravel HTTP Client 中, 如果要使用 CLI 安裝 guzzle, 該怎麼做?
composer require guzzlehttp/guzzle




# Making Requests

Laravel HTTP Client 中, 如果我要發一個最簡單的 request, 在以下的 example 中, 該怎麼做?
  • Example:

    <?php
    use Illuminate\Support\Facades\Http;

    $response = 這裡是?('http://test.com');
  • Answer:

    <?php
    use Illuminate\Support\Facades\Http;

    $response = Http::get('http://test.com');
Laravel HTTP Client 中, 以下 example 中的 $response 是哪個 class 的 instance?
  • Example:

    <?php
    $response->body() : string;
    $response->json() : array;
    $response->status() : int;
    $response->ok() : bool;
    $response->successful() : bool;
    $response->serverError() : bool;
    $response->clientError() : bool;
    $response->header($header) : string;
    $response->headers() : array;
  • Answer:
    Illuminate\Http\Client\Response

Laravel HTTP Client 中, 如果我要直接取得 JSON response data 中的 ‘name’, 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    return Http::get('http://test.com/users/1')這裡是?;
  • Answer:

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


# Request Data

Laravel HTTP Client 中, 預設發 request 的 content type 是?

application/json

Laravel HTTP Client 中, 如果我要夾帶參數, ‘name’ => ‘Steve’, 以及 ‘role’ => ‘Network Administrator’, 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    $response = Http::post('http://test.com/users', [
    // 這裡是?
    ]);
  • Answer:

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


# Sending Form URL Encoded Requests

Laravel HTTP Client 中, 如果我要使用 application/x-www-form-urlencoded 的方式來發送 request, 在以下的 example 中, 該使用哪個 method?
  • Example:

    <?php
    $response = Http::這裡是?()->post('http://test.com/users', [
    'name' => 'Sara',
    'role' => 'Privacy Consultant',
    ]);
  • Answer:

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


# Multi-Part Requests

Laravel HTTP Client 中, 如果我要使用 multi-part 方式來發送 request, 在以下的 example 中, 該使用哪個 method?
  • Example:

    <?php
    $response = Http::這裡是?(
    'attachment', file_get_contents('photo.jpg'), 'photo.jpg'
    )->post('http://test.com/attachments');
  • Answer:

    <?php
    $response = Http::attach(
    'attachment', file_get_contents('photo.jpg'), 'photo.jpg'
    )->post('http://test.com/attachments');
Laravel HTTP Client 中, 在以下的 multi-part example, attach method 的第一個 argument 代表的意思是?
  • Example:

    <?php
    $response = Http::attach(
    'attachment', file_get_contents('photo.jpg'), 'photo.jpg'
    )->post('http://test.com/attachments');
  • Answer:
    欄位名稱

Laravel HTTP Client 中, 在以下的 multi-part example, attach method 的第二個 argument 代表的意思是?
  • Example:

    <?php
    $response = Http::attach(
    'attachment', file_get_contents('photo.jpg'), 'photo.jpg'
    )->post('http://test.com/attachments');
  • Answer:
    檔案來源

Laravel HTTP Client 中, 在以下的 multi-part example, attach method 的第三個 argument 代表的意思是?
  • Example:

    <?php
    $response = Http::attach(
    'attachment', file_get_contents('photo.jpg'), 'photo.jpg'
    )->post('http://test.com/attachments');
  • Answer:
    檔名

Laravel HTTP Client 中, 在以下的 multi-part example, 是用什麼方式來傳送檔案?
  • Example:

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

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


# Headers

Laravel HTTP Client 中, 如果我要定義 request 的 header, 在以下的 example 中該使用哪個 method?
  • Example:

    <?php
    $response = Http::這裡是?([
    'X-First' => 'foo',
    'X-Second' => 'bar'
    ])->post('http://test.com/users', [
    'name' => 'Taylor',
    ]);
  • Answer:

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

# Authentication

Laravel HTTP Client 中, 若要附加 basic auth 到 request, 在以下的 example 中, 該使用哪個 method?
  • Example:

    <?php
    // Basic authentication...
    $response = Http::這裡是?('taylor@laravel.com', 'secret')->post(...);
  • Answer:

    <?php
    // Basic authentication...
    $response = Http::withBasicAuth('taylor@laravel.com', 'secret')->post(...);
Laravel HTTP Client 中, 若要附加 digest auth 到 request, 在以下的 example 中, 該使用哪個 method?
  • Example:

    <?php
    // Digest authentication...
    $response = Http::withDigestAuth('taylor@laravel.com', 'secret')->post(...);
  • Answer:

    <?php
    // Digest authentication...
    $response = Http::withDigestAuth('taylor@laravel.com', 'secret')->post(...);


# Bearer Tokens

Laravel HTTP Client 中, 若要附加 bearer token 到 request, 在以下的 example 中, 該使用哪個 method?
  • Example:

    <?php
    $response = Http::這裡是?('token')->post(...);
  • Answer:

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


# Timeout

Laravel HTTP Client 中, 若要定義 request 的 timeout, 也就是等待 response 的最大時間, 在以下的 example 中, 該使用哪個 method?
  • Example:

    <?php
    $response = Http::這裡是?(3)->get(...);
  • Answer:

    <?php
    $response = Http::timeout(3)->get(...);
Laravel HTTP Client 中, 如果 timeout 超過了, 會丟出哪個 instance?

Illuminate\Http\Client\ConnectionException instance


# Retries

Laravel HTTP Client 中, 如果我要定義 request 的重試, 那在以下的 example 中, 該使用哪個 method?
  • Example:

    <?php
    $response = Http::這裡是?(3, 100)->post(...);
  • Answer:

    <?php
    $response = Http::retry(3, 100)->post(...);
Laravel HTTP Client 中, 以下的 HTTP request example, 3 和 100 分別代表什麼意思?
  • Example:

    <?php
    $response = Http::retry(3, 100)->post(...);
  • Answer:
    3 代表 retry 次數
    100 retry 與 retry 之間, Laravel 該等多少 milliseconds

Laravel HTTP Client 中, 以下的 HTTP request example, 如果所有 retry 都失敗了, Laravel 會回傳哪個 instance?
  • Example:

    <?php
    $response = Http::retry(3, 100)->post(...);
  • Answer:
    Illuminate\Http\Client\RequestException instance


# Error Handling

Laravel HTTP Client 中, 要是 request 出現 error, HTTP client 會立即 throw error 嗎?

不會

Laravel HTTP Client 中, 要是 request 出現 error, HTTP client 並不會立即 throw error, 那如果我要判斷 error 是否 400 level 的, 在以下的 example 中, 該使用哪個 method??
  • Example:

    <?php
    // Determine if the response has a 400 level status code...
    $response->這裡是?();
  • Answer:

    <?php
    // Determine if the response has a 400 level status code...
    $response->clientError();
Laravel HTTP Client 中, 要是 request 出現 error, HTTP client 並不會立即 throw error, 那如果我要判斷 status code 是否介於 200~299, 在以下的 example 中, 該使用哪個 method??
  • Example:

    <?php
    // Determine if the status code was >= 200 and < 300...
    $response->這裡是?();
  • Answer:

    <?php
    // Determine if the status code was >= 200 and < 300...
    $response->successful();
Laravel HTTP Client 中, 要是 request 出現 error, HTTP client 並不會立即 throw error, 那如果我要判斷 error 是否 500 level 的, 在以下的 example 中, 該使用哪個 method??
  • Example:

    <?php
    // Determine if the response has a 500 level status code...
    $response->這裡是?();
  • Answer:

    <?php
    // Determine if the response has a 500 level status code...
    $response->serverError();


# Throwing Exceptions

Laravel HTTP Client 中, 要是 request 出現 error, HTTP Client 並不會立即 throw error, 若是我要出錯了就自動的拋出 Illuminate\Http\Client\RequestException, 在以下的 example 中該使用哪個 method?
  • Example:

    <?php
    $response = Http::post(...);

    // Throw an exception if a client or server error occurred...
    $response->這裡是?();

    return $response['user']['id'];
  • Answer:

    <?php
    $response = Http::post(...);

    // Throw an exception if a client or server error occurred...
    $response->throw();

    return $response['user']['id'];
Laravel HTTP Client 中, 在以下的 example 若是出現 client error or server error, 會拋出哪個 class 的 instance?
  • Example:

    <?php
    $response = Http::post(...);

    // Throw an exception if a client or server error occurred...
    $response->throw();

    return $response['user']['id'];
  • Answer:
    Illuminate\Http\Client\RequestException

Laravel HTTP Client 中, 當出錯了, 拋出一個 Illuminate\Http\Client\RequestException instance 時, 可從該 instance 的哪個 public property 取得 response?

$response property

Laravel HTTP Client 中, 以下的 example 中, 若是沒有出現錯誤, 會拋出 exception 嗎?
  • Example:

    <?php
    return Http::post(...)->throw()->json();
  • Answer:
    不會


# Guzzle Options

Laravel HTTP Client 中, 如果我要附加額外的 request options, 在以下的 example 中, 可以使用哪個 method?
  • Example:

    <?php
    $response = Http::這裡是?([
    'debug' => true,
    ])->get('http://test.com/users');
  • Answer:

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




# Testing

# Faking Responses

以下的 Laravel example code 的意思是?
  • Example:

    <?php
    use Illuminate\Support\Facades\Http;

    Http::fake();

    $response = Http::post(...);
  • Answer:
    當使用 Http 的 fake() 並不帶任何參數時, 會發送一個 fake request, 並且都會 return status code 200 response


# Faking Specific URLs

Laravel HTTP Client 中, 當我們在寫 testing 時, 希望可以自定義一個假的 response, 若我想要定義 request 的 url 以及其 response, 在以下的 example 中, 可以使用哪個 method?
  • Example:

    <?php
    Http::這裡是?([
    // Stub a JSON response for GitHub endpoints...
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),

    // Stub a string response for Google endpoints...
    'google.com/*' => Http::response('Hello World', 200, ['Headers']),
    ]);
  • Answer:

    <?php
    Http::fake([
    // Stub a JSON response for GitHub endpoints...
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),

    // Stub a string response for Google endpoints...
    'google.com/*' => Http::response('Hello World', 200, ['Headers']),
    ]);
Laravel HTTP Client 中, 以下的 example 中的 * 代表的意思是?

wildcard

Laravel HTTP Client 中, 在以下的 example 有兩個 fake entries, 如果第二個 entry, 我想要定義成, 只要 url 不符合第一個 entry patten, 都要回第二個 entry 的 response, 那該使用怎樣的 url?
  • Example:

    <?php
    Http::fake([
    // Stub a JSON response for GitHub endpoints...
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),

    // Stub a string response for all other endpoints...
    '這裡是?' => Http::response('Hello World', 200, ['Headers']),
    ]);
  • Answer:

    <?php
    Http::fake([
    // Stub a JSON response for GitHub endpoints...
    'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),

    // Stub a string response for all other endpoints...
    '*' => Http::response('Hello World', 200, ['Headers']),
    ]);


# Faking Response Sequences

Laravel HTTP Client 中, 有時我們可能會需要指定一個 url, 這個 url 會依序的 return 預先定義的 fake responses, 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    Http::fake([
    // Stub a series of responses for GitHub endpoints...
    'github.com/*' => Http::這裡是?()
    ->push('Hello World', 200)
    ->push(['foo' => 'bar'], 200)
    ->pushStatus(404),
    ]);
  • Answer:

    <?php
    Http::fake([
    // Stub a series of responses for GitHub endpoints...
    'github.com/*' => Http::sequence()
    ->push('Hello World', 200)
    ->push(['foo' => 'bar'], 200)
    ->pushStatus(404),
    ]);
Laravel HTTP Client 中, 有時我們可能會需要指定一個 url, 這個 url 會依序的 return 預先定義的 fake responses, 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    Http::fake([
    // Stub a series of responses for GitHub endpoints...
    'github.com/*' => Http::sequence()
    ->這裡是?('Hello World', 200)
    ->這裡是?(['foo' => 'bar'], 200)
    ->pushStatus(404),
    ]);
  • Answer:

    <?php
    Http::fake([
    // Stub a series of responses for GitHub endpoints...
    'github.com/*' => Http::sequence()
    ->push('Hello World', 200)
    ->push(['foo' => 'bar'], 200)
    ->pushStatus(404),
    ]);
Laravel HTTP Client 中, 有時我們可能會需要指定一個 url, 這個 url 會依序的 return 預先定義的 fake responses, 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    Http::fake([
    // Stub a series of responses for GitHub endpoints...
    'github.com/*' => Http::sequence()
    ->push('Hello World', 200)
    ->push(['foo' => 'bar'], 200)
    ->這裡是?(404),
    ]);
  • Answer:

    <?php
    Http::fake([
    // Stub a series of responses for GitHub endpoints...
    'github.com/*' => Http::sequence()
    ->push('Hello World', 200)
    ->push(['foo' => 'bar'], 200)
    ->pushStatus(404),
    ]);
Laravel HTTP Client 中, 有時我們可能會需要指定一個 url, 這個 url 會依序的 return 預先定義的 fake responses, 在以下的 example 中, 當預先定義好的 response 全部都 return 了之後, 會自動 throw exception, 如果我要定義這個 default 的 exception, 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    Http::fake([
    // Stub a series of responses for GitHub endpoints...
    'github.com/*' => Http::sequence()
    ->push('Hello World', 200)
    ->push(['foo' => 'bar'], 200)
    ->這裡是?(Http::response()),
    ]);
  • Answer:

    <?php
    Http::fake([
    // Stub a series of responses for GitHub endpoints...
    'github.com/*' => Http::sequence()
    ->push('Hello World', 200)
    ->push(['foo' => 'bar'], 200)
    ->whenEmpty(Http::response()),
    ]);
Laravel HTTP Client 中, 如果我要定義一系列有順序的 fake response, 但是不定義 url, 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    Http::這裡是?()
    ->push('Hello World', 200)
    ->whenEmpty(Http::response());
  • Answer:

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


# Fake Callback

Laravel HTTP Client 中, 如果我需要更複雜的邏輯來判斷該 return 怎樣的 fake response, 在以下的 example 中, 帶入 fake method 的 argument 是?
  • Example:

    <?php
    Http::fake(這裡是?);
  • Answer:

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


# Inspecting Requests

Laravel HTTP Client 中, 有時當我們使用 fake response 時, 可能會想要檢查對方收到的 data 是否跟我傳送出去的一樣, 在以下的 example 中, 可以在使用 fake method 之後立即呼叫哪個 method?
  • Example:

    <?php
    Http::fake();

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

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

    <?php
    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';
    });
Laravel HTTP Client 中, 有時當我們使用 fake response 時, 可能會想要對方收到的 data 是否跟我傳送出去的一樣, 如果我的判斷邏輯是 該 url 並沒有被送出, 沒有回 true, 有則回 false, 在以下的 example 中, 可以在使用 fake method 之後立即呼叫哪個 method?
  • Example:

    <?php
    Http::fake();

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

    Http::這裡是?(function (Request $request) {
    return $request->url() === 'http://test.com/posts';
    });
  • Answer:

    <?php
    Http::fake();

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

    Http::assertNotSent(function (Request $request) {
    return $request->url() === 'http://test.com/posts';
    });
Laravel HTTP Client 中, 有時當我們使用 fake response 時, 可能會想要對方收到的 data 是否跟我傳送出去的一樣, 如果我的判斷邏輯是 沒有送出任何東西, 沒有則回 true, 有則回 false, 在以下的 example 中, 可以在使用 fake method 之後立即呼叫哪個 method?
  • Example:

    <?php
    Http::fake();

    Http::這裡是?();
  • Answer:

    <?php
    Http::fake();

    Http::assertNothingSent();
Kubernetes - Using RBAC Authorization Laravel - Security - Password Reset

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×