如何使用 Laravel 内置客户端与外部 API 交互
已发表: 2023-04-24Laravel 使 API 交互对于新手和有经验的 Web 开发人员来说都变得轻而易举。 Larvel HTTP 客户端构建在 PHP 的 Guzzle HTTP 客户端之上,为开发人员提供更流畅的 HTTP 请求体验。 其主要功能包括身份验证、路由和有效的对象关系映射 (ORM)。
本文将探索使用 Laravel 的 HTTP 客户端发出请求、调试响应、创建中间件和宏等。
Laravel HTTP Client 为您完成 API 的艰苦工作
Guzzle 是一个简单的 PHP HTTP 客户端。 它为不同的表单请求提供功能,包括GET
、 POST
、 PUT
和DELETE
以及流功能和多部分请求。 使用 Guzzle HTTP 客户端,可以向服务器发送同步和异步请求。 此外,它还带有合适的中间件来定制客户端的行为。
Laravel 的 HTTP 客户端是一个基于 Guzzle 构建的包装器,但具有额外的功能。 它包括对重试失败请求的支持和一些带有 JSON 数据的辅助函数。 Laravel HTTP 客户端的大部分功能与 Guzzle 相似。
先决条件
在接下来的部分中,您将了解有关 Laravel 的 HTTP 客户端的更多信息。 要继续,您将需要:
- Laravel、PHP 和 API 的基础知识
- 安装了 PHP 和 Composer
- 邮差
如何提出请求
要了解如何使用 HTTP 客户端发出请求,您可以利用大量托管 API,例如 ReqRes。
首先导入创建应用程序时包含的 HTTP 包。 在App/Http/Controllers/UserController.php文件中,添加以下代码,从文件开头的 use 语句开始,剩下的代码在 index 函数中。
use Illuminate\Support\Facades\Http; return Http::get("https://reqres.in/api/users?page=2");
注意:对于复杂的用例,您还可以使用withHeaders
方法发送带有标头的请求。
在同一文件中,使用以下代码创建一个新的方法帖子:
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 并添加 http://127.0.0.1:8000/post 作为 URL,请求类型为GET
。 单击发送后,您将看到以下响应:
并发请求
并行请求可以显着提高性能,因为您可以在同一时期获取更多数据。 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']);
访问路由时,浏览器给出如下响应:
请求宏
请求宏在与通用 API 路径交互时很有用。
要创建宏,您需要使用以下代码在app/Http/Providers/AppServiceProvider.php文件的引导方法中定义宏:
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 请求成功,您可以使用客户端中包含的状态方法。 该方法获取服务器发送的状态码并显示出来。
要对此进行测试,请将之前的宏代码替换为App/Http/Controllers/UserController.php文件中的以下代码:
function macro() { $response = Http::reqres()->get('/users?page=2'); return $response->status(); }
在这里,状态码 200 表示请求成功。
如何测试 JSON API
Laravel 有几个助手来测试 JSON API 及其响应。 辅助函数包括json 、 getJson 、 postJson 、 putJson 、 patchJson 、 deleteJson等。
为了更好地理解测试,为GET
用户的路由创建一个测试场景。 当您引导 Laravel 应用程序时,示例测试已经创建。 在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); } }
添加的代码在用户的路由中获取 JSON 数据并检查状态代码是否为 200。
添加测试代码后,在终端中运行以下命令以运行测试:
./vendor/bin/phpunit
测试完成后,您会看到它运行了两个测试,都成功了。
同样,您可以检查不同类型的请求并使用其他辅助方法进行更复杂的测试。
如何处理事件
Laravel 提供了三个在处理 HTTP 请求时触发的事件。
- RequestSending ,在发送请求之前。
- ResponseReceived ,这是收到响应的时间。
- ConnectionFailed ,即未收到响应时。
所有三个事件都包含$request
属性以检查Illuminate\Http\Client\Request
实例,并且ResponseReceived
有一个额外的$response property
。 这些对于在事件发生后执行操作特别有用。 例如,您可能希望在收到成功回复后发送电子邮件。
要创建事件和侦听器,请导航到app/Providers/EventServiceProvider.php文件并将侦听数组替换为以下代码。
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) { } }
终端打印状态码的信息日志。
概括
无论网站或 Web 应用程序是由组织还是独立开发人员制作的,API 都是其成功的关键。 但是,使用它们可能很困难。
许多框架和库承诺会简化这个过程,但 Laravel 以其对简单性和易用性的关注而脱颖而出。 他们的内置客户端支持简单的 API 调用、并发 API 调用、API 宏、基于 JSON 的 API 的辅助方法等。