Chào mừng các bạn đến với CodeTutHub! Trong thế giới phát triển ứng dụng web hiện đại, việc giao tiếp với các API bên ngoài là một phần không thể thiếu. Dù là tích hợp với các dịch vụ thanh toán, lấy dữ liệu từ một API công cộng, hay giao tiếp với các microservice nội bộ, bạn đều cần một công cụ mạnh mẽ và dễ sử dụng để gửi các HTTP request.
May mắn thay, Laravel cung cấp một HTTP Client mạnh mẽ và biểu cảm ngay từ đầu, được xây dựng dựa trên thư viện Guzzle HTTP Client. Nó cung cấp một API rõ ràng, đơn giản để thực hiện các yêu cầu HTTP nhanh chóng và hiệu quả.
Trong bài viết này, chúng ta sẽ cùng nhau khám phá mọi khía cạnh của Laravel 12 HTTP Client, từ những yêu cầu cơ bản đến các tính năng nâng cao, giúp bạn dễ dàng giao tiếp với bất kỳ API nào.
HTTP Client trong Laravel là gì?
Laravel HTTP Client là một lớp wrapper tiện lợi xung quanh thư viện Guzzle HTTP Client phổ biến. Nó cung cấp một cú pháp fluent (linh hoạt) và dễ đọc để gửi các yêu cầu HTTP (GET, POST, PUT, DELETE, v.v.) và xử lý các phản hồi.
Tại sao nên sử dụng Laravel HTTP Client?
- Cú pháp biểu cảm, dễ đọc: Dễ dàng tạo và hiểu các yêu cầu HTTP.
- Tích hợp sâu với Laravel: Tận dụng hệ sinh thái của Laravel như cấu hình, testing.
- Tính năng mạnh mẽ: Hỗ trợ xử lý lỗi, retry, timeout, xác thực, concurrency và nhiều hơn nữa.
- Testing dễ dàng: Cung cấp cơ chế "faking" phản hồi để kiểm thử API một cách thuận tiện.
1. Bắt đầu với các request cơ bản
Laravel HTTP Client được tích hợp sẵn, bạn không cần cài đặt thêm package nào. Bạn có thể bắt đầu sử dụng nó bằng cách dùng Facade Http.
GET
Để gửi một GET request đơn giản, bạn chỉ cần gọi phương thức get():
use Illuminate\Support\Facades\Http;
// Gửi yêu cầu GET tới một URL
$response = Http::get('https://jsonplaceholder.typicode.com/posts/1');
// Lấy dữ liệu phản hồi dạng JSON và chuyển đổi thành mảng/đối tượng PHP
$data = $response->json();
// In ra dữ liệu để kiểm tra
dd($data);
POST
Để gửi yêu cầu POST, bạn sử dụng phương thức post() và truyền một mảng dữ liệu làm tham số thứ hai:
use Illuminate\Support\Facades\Http;
$response = Http::post('https://jsonplaceholder.typicode.com/posts', [
'title' => 'Foo',
'body' => 'Bar',
'userId' => 1,
]);
// Lấy dữ liệu phản hồi dạng JSON
$data = $response->json();
dd($data);
Mặc định, Laravel HTTP Client sẽ tự động gửi dữ liệu dưới dạng application/json.
Các phương thức HTTP khác
Bạn có thể sử dụng các phương thức tương tự cho các loại yêu cầu HTTP khác:
Http::put($url, $data)Http::patch($url, $data)Http::delete($url)
2. Xử lý phản hồi (Responses)
Đối tượng $response mà bạn nhận được sau khi gửi request cung cấp nhiều phương thức tiện lợi để kiểm tra và truy cập dữ liệu phản hồi.
Kiểm tra trạng thái phản hồi
$response->ok(): Trả vềtruenếu mã trạng thái (status code) nằm trong khoảng200-299.$response->successful(): Tương tự nhưok().$response->redirect(): Trả vềtruenếu mã trạng thái là chuyển hướng (300-399).$response->clientError(): Trả vềtruenếu mã trạng thái là lỗi client (400-499).$response->serverError(): Trả vềtruenếu mã trạng thái là lỗi server (500-599).$response->failed(): Trả vềtruenếu mã trạng thái nằm trong khoảng400hoặc500.$response->status(): Trả về mã trạng thái HTTP (ví dụ:200,404,500).
if ($response->successful()) {
echo "Request thành công!";
} else {
echo "Request thất bại với mã trạng thái: " . $response->status();
}
Truy cập dữ liệu phản hồi
$response->body(): Trả về toàn bộ nội dung phản hồi dưới dạng chuỗi.$response->json(): Chuyển đổi nội dung phản hồi JSON thành mảng (associative array) PHP.$response->object(): Chuyển đổi nội dung phản hồi JSON thành đối tượng PHP.$response->collect(): Chuyển đổi nội dung phản hồi JSON thành một Laravel Collection.$response->collect('key_name'): Chuyển đổi một phần của JSON thành Collection.
// JSON response: {"message": "Success", "data": {"id": 1, "name": "Test"}}
$jsonArray = $response->json(); // Output: ['message' => 'Success', 'data' => ['id' => 1, 'name' => 'Test']]
$object = $response->object(); // Output: object with properties message, data
echo $jsonArray['message'];
echo $object->data->name;
Truy cập Headers
$response->headers(): Trả về tất cả các headers dưới dạng array.$response->header('Header-Name'): Trả về value của một header cụ thể.
$contentType = $response->header('Content-Type');
dd($contentType);
3. Tùy chỉnh request
Laravel HTTP Client cung cấp một giao diện fluent để tùy chỉnh request của bạn.
Request Header
Sử dụng phương thức withHeaders() để thêm các header tùy chỉnh:
$response = Http::withHeaders([
'X-Custom-Header' => 'MyValue',
'Authorization' => 'Bearer your_token_here',
])->post('https://example.com/api/data', ['key' => 'value']);
Gửi dữ liệu Form URL-Encoded
Mặc định, dữ liệu post, put, patch được gửi dưới dạng JSON. Nếu bạn cần gửi application/x-www-form-urlencoded (giống như form HTML thông thường), hãy sử dụng asForm():
$response = Http::asForm()->post('https://example.com/api/data', [
'name' => 'John Doe',
'email' => 'john@example.com',
]);
Gửi dữ liệu Multipart (File Upload)
Để gửi file (multipart/form-data), bạn sử dụng phương thức attach():
$response = Http::attach(
'attachment', // Tên trường input
file_get_contents('path/to/your/file.jpg'), // Nội dung file
'my_photo.jpg' // Tên file hiển thị
)->post('https://example.com/api/upload');
// Hoặc từ một đường dẫn file:
$response = Http::attach(
'attachment',
Storage::get('photos/avatar.jpg'), // Lấy nội dung file từ Storage
'avatar.jpg',
['Content-Type' => 'image/jpeg'] // Tùy chọn: thiết lập Content-Type
)->post('https://example.com/api/upload');
Xác thực (Authentication)
- Basic Authentication:
$response = Http::withBasicAuth('username', 'password')->get('https://example.com/api/protected'); - Bearer Token Authentication:
$response = Http::withToken('your_jwt_token')->get('https://example.com/api/protected');
Thêm Query Parameters
Sử dụng withQueryParameters() hoặc truyền trực tiếp vào get():
// Cách 1: Truyền trực tiếp vào get()
$response = Http::get('https://jsonplaceholder.typicode.com/posts', [
'userId' => 1,
'_limit' => 10,
]);
// Cách 2: Dùng withQueryParameters() (có thể dùng với các phương thức khác)
$response = Http::withQueryParameters([
'userId' => 1,
'_limit' => 10,
])->get('https://jsonplaceholder.typicode.com/posts');
4. Xử lý lỗi và Retries
Laravel HTTP Client cung cấp các cách linh hoạt để xử lý lỗi và tự động thử lại request.
Xử lý lỗi HTTP
Nếu bạn muốn một ngoại lệ (exception) được ném ra khi có lỗi client (4xx) hoặc server (5xx), hãy gọi phương thức throw():
try {
$response = Http::get('https://example.com/api/nonexistent-endpoint')->throw();
// Xử lý phản hồi thành công
} catch (\Illuminate\Http\Client\RequestException $e) {
if ($e->response->clientError()) {
echo "Lỗi Client (4xx): " . $e->getMessage();
} elseif ($e->response->serverError()) {
echo "Lỗi Server (5xx): " . $e->getMessage();
}
}
Bạn cũng có thể gọi throwIf($condition) hoặc throwUnless($condition) để ném ngoại lệ có điều kiện.
Thử lại request (Retries)
Khi request thất bại (ví dụ: lỗi network, lỗi server tạm thời), bạn có thể cấu hình HTTP Client để tự động thử lại:
// Thử lại 3 lần nếu request thất bại, với độ trễ 100ms giữa các lần
$response = Http::retry(3, 100)->get('https://example.com/api/flaky-service');
// Thử lại với hàm callback để kiểm tra điều kiện retry
$response = Http::retry(3, 100, function ($exception, $request) {
return $exception instanceof ConnectionException; // Chỉ retry nếu lỗi kết nối
})->get('https://example.com/api/data');
Timeout
Để ngăn request treo với thời gian quá lâu, bạn có thể thiết lập thời gian chờ:
// Timeout sau 5 giây
$response = Http::timeout(5)->get('https://example.com/api/slow-service');
// Timeout kết nối sau 3 giây và timeout phản hồi sau 5 giây
$response = Http::timeout(5)->connectTimeout(3)->get('https://example.com/api/slow-service');
5. Gửi nhiều request song song (Concurrent Requests)
Nếu bạn cần gửi nhiều request độc lập cùng một lúc, bạn có thể làm điều đó một cách hiệu quả với pool():
use Illuminate\Http\Client\Pool;
$responses = Http::pool(fn (Pool $pool) => [
$pool->get('https://jsonplaceholder.typicode.com/posts/1'),
$pool->get('https://jsonplaceholder.typicode.com/comments/1'),
$pool->get('https://jsonplaceholder.typicode.com/todos/1'),
]);
// Truy cập các phản hồi riêng lẻ bằng index
$post = $responses[0]->json();
$comment = $responses[1]->json();
$todo = $responses[2]->json();
dd($post, $comment, $todo);
6. Macro
Bạn có thể định nghĩa các "macro" tùy chỉnh cho HTTP Client để dễ dàng sử dụng lại các cấu hình request phổ biến. Ví dụ, nếu bạn thường xuyên gọi một API cụ thể:
// Trong AppServiceProvider's boot method
use Illuminate\Support\Facades\Http;
Http::macro('github', function () {
return Http::withHeaders([
'X-GitHub-Api-Version' => '2022-11-28',
'Accept' => 'application/vnd.github+json',
])->baseUrl('https://api.github.com');
});
// Cách sử dụng:
$response = Http::github()->get('/user');
dd($response->json());
7. Testing HTTP Requests
Laravel cung cấp một cơ chế mạnh mẽ để "giả lập" (fake) các request HTTP, giúp bạn kiểm thử ứng dụng mà không cần phải gửi request thực sự đến các API bên ngoài.
Faking Responses
use Illuminate\Support\Facades\Http;
// Trong file test của bạn (ví dụ: tests/Feature/ApiTest.php)
class ApiTest extends TestCase
{
public function test_user_can_be_fetched_from_api()
{
// Giả lập phản hồi cho bất kỳ request GET nào tới /users
Http::fake([
'jsonplaceholder.typicode.com/users/*' => Http::response(['id' => 1, 'name' => 'Fake User'], 200),
]);
$response = Http::get('https://jsonplaceholder.typicode.com/users/1');
$this->assertEquals('Fake User', $response->json('name'));
}
public function test_multiple_faked_responses()
{
Http::fake([
// Phản hồi cho một URL cụ thể
'jsonplaceholder.typicode.com/posts/1' => Http::response(['title' => 'First Post'], 200),
// Phản hồi cho một URL có wildcard
'jsonplaceholder.typicode.com/posts/*' => Http::response(['title' => 'Any Post'], 200),
// Phản hồi với lỗi 500
'jsonplaceholder.typicode.com/error' => Http::response('Server Error', 500),
]);
$response1 = Http::get('https://jsonplaceholder.typicode.com/posts/1');
$response2 = Http::get('https://jsonplaceholder.typicode.com/posts/5');
$response3 = Http::get('https://jsonplaceholder.typicode.com/error');
$this->assertEquals('First Post', $response1->json('title'));
$this->assertEquals('Any Post', $response2->json('title'));
$this->assertEquals(500, $response3->status());
}
}
Kiểm tra các request đã gửi (Asserting Requests)
Bạn cũng có thể kiểm tra xem ứng dụng của bạn có gửi các request HTTP cụ thể hay không:
use Illuminate\Support\Facades\Http;
Http::fake();
// Trong code của bạn, gửi một request
Http::post('https://example.com/orders', ['item' => 'Laptop']);
// Trong file test
Http::assertSent(function ($request) {
return $request->url() == 'https://example.com/orders' &&
$request->method() == 'POST' &&
$request->data()['item'] == 'Laptop';
});
// Kiểm tra xem request nào đó đã được gửi và không được gửi
Http::assertSentCount(1); // Chỉ có 1 request được gửi
Http::assertNotSent(function ($request) {
return $request->url() == 'https://example.com/products';
});
Kết luận
Laravel HTTP Client là một công cụ cực kỳ mạnh mẽ và linh hoạt, giúp đơn giản hóa đáng kể việc giao tiếp với các API bên ngoài trong ứng dụng Laravel của bạn. Từ việc gửi các request đơn giản đến xử lý phản hồi phức tạp, xác thực, thử lại và kiểm thử, nó cung cấp mọi thứ bạn cần để tích hợp hiệu quả với thế giới bên ngoài.
Hy vọng bài viết này đã cung cấp cho bạn một cái nhìn tổng quan và chi tiết về cách sử dụng Laravel 12 HTTP Client. Hãy bắt đầu áp dụng nó vào các dự án của bạn ngay hôm nay để thấy sự khác biệt!
Nếu bạn có bất kỳ câu hỏi hoặc mẹo nào khác về HTTP Client, đừng ngần ngại chia sẻ trong phần bình luận bên dưới nhé!









