本篇文章給大家帶來了關于laravel的相關知識,其中主要跟大家分享5個laravel http client的小技巧,感興趣的朋友下面一起來看一下吧,希望對大家有幫助。
作為web開發人員,我們經常需要與來自Laravel應用程序的api進行交互。在Laravel HTTP客戶端版本7中提供了一個方便而直觀的Guzzle HTTP庫包裝器。在本文中,我們將探討使用Laravel HTTP Client的五個有價值的技巧,這些技巧可以使你的開發體驗更加高效和愉快。
這些技巧包括使用HTTP宏、為容器服務配置HTTP客戶機、可移植的基本URL配置、防止測試中的雜發請求以及偵聽HTTP事件。通過掌握這些技巧,你可以簡化API交互并創建更健壯和可維護的Laravel應用程序。
HTTP 宏
Laravel 的許多服務都有一個宏特性,允許你為應用程序定義自定義方法。你可以將這些宏添加到服務提供者的boot()方法中,而不是從 Laravel 框架擴展核心類。
HTTP 文檔中展示了一個宏的示例,你可以使用它來定義常見的設置:
public function boot(): void { Http::macro('github', function () { return Http::withHeaders([ 'X-Example' => 'example', ])->baseUrl('https://github.com'); }); } // Usage response = Http::github()->get('/');
宏可以定義任何你想在應用程序中定義和重復使用的便捷方法。文檔中的宏示例涉及到了另一個配置 HTTP 客戶端用于在其他服務中使用的提示。
在下一節中,我們將重溫將宏與傳遞客戶端到其他容器服務相結合的方法。
配置容器服務的 HTTP 客戶端
在 Laravel 應用程序中與 API 交互時,你可能希望為客戶端配置各種可配置的設置。例如,如果 API 具有多個環境,則需要配置基本 URL、令牌、超時設置等。
我們可以利用宏來定義客戶端,將客戶端表示為自己的服務,然后將其注入到其他服務中,或者兩者都有。
首先,讓我們看看如何在服務提供者的 register() 方法中定義客戶端設置:
public function register(): void { $this->app->singleton(ExampleService::class, function (Application $app) { $client = Http::withOptions([ 'base_uri' => config('services.example.base_url'), 'timeout' => config('services.example.timeout', 10), 'connect_timeout' => config('services.example.connect_timeout', 2), ])->withToken(config('services.example.token')); return new ExampleService($client); }); }
在單例服務定義中,我們鏈式調用了一些調用以配置客戶端。結果是一個 PendingRequest 實例,我們可以將其傳遞給我們的服務構造函數,如下所示:
class ExampleService { public function __construct( private PendingRequest $client ) {} public function getWidget(string $uid) { $response = $this->client ->withUrlParameters(['uid' => $uid]) ->get('widget/{uid}'); return new Widget($response->json()); } }
該服務使用 withOptions() 方法直接配置 Guzzle 選項,但我們也可以使用 HTTP 客戶端提供的一些便捷方法:
$this->app->singleton(ExampleService::class, function (Application $app) { $client = Http::baseUrl(config('services.example.base_url')) ->timeout(config('services.example.timeout', 10)) ->connectTimeout(config('services.example.connect_timeout', 2)) ->withToken(config('services.example.token')); return new ExampleService($client); });
或者,如果你想將宏與服務相結合,可以在你的 AppServiceProvider 的 boot() 方法中使用你定義的宏:
$this->app->singleton(ExampleService::class, function (Application $app) { return new ExampleService(Http::github()); });
可移植的基礎 URL 配置
你可能已經看到默認的基礎 URL 包含一個尾隨的 /,根據 示例,這提供了最大的可移植性。
以下面的服務配置為例 (注意默認的 base_url):
return [ 'example' => [ 'base_url' => env('EXAMPLE_BASE_URI', 'https://api.example.com/v1/'), 'token' => env('EXAMPLE_SERVICE_TOKEN'), 'timeout' => env('EXAMPLE_SERVICE_TIMEOUT', 10), 'connect_timeout' => env('EXAMPLE_SERVICE_TIMEOUT', 2), ], ];
如果我們的 API 在生產和測試環境中有一個路徑前綴 /v1/ ,也許它只是 https://stg-api.example.com/; 使用尾部斜線可以使 URL 按預期工作,而不會更改代碼。在配置尾部 / 的同時,請注意,我的代碼中的所有 API 調用都使用相對路徑:
$this->client ->withUrlParameters(['uid' => $uid]) // 例子: // 測試環境 - https://stg-api.example.com/widget/123 // 生產環境 - https://api.example.com/v1/widget/123 ->get('widget/{uid}');
請參閱 Guzzle 的示例文檔,了解不同的 base_uri 風格是如何影響 URI 的解析的。
防止測試中的雜散請求
Laravel 的 HTTP 客戶端提供了優秀的測試工具,使編寫測試變得輕而易舉。當我寫與 API 交互的代碼時,我感到不安的是我的測試在某種程度上有實際的網絡請求發生。進入示例與 Laravel 的 HTTP 客戶端:
Http::preventStrayRequests(); Http::fake([ ????'github.com/*'?=>?Http::response('ok'), ]); //?Run?test?code //?If?any?other?code?triggers?an?HTTP?call?via?Laravel's?client //?an?exception?is?thrown.
在我看來,使用 preventStrayRequests() 的最好方法是在你期望與 API 交互的測試類中定義一個 setUp() 方法。也許你也可以把它添加到你的應用程序的基礎 TestCase 類中。
namespace Tests; use IlluminateFoundationTestingTestCase as BaseTestCase; use IlluminateSupportFacadesHttp; abstract class TestCase extends BaseTestCase { use CreatesApplication; public function setUp(): void { parent::setUp(); Http::preventStrayRequests(); } }
這樣做將確保你的測試套件中觸發的每個 HTTP 客戶端調用都有一個假的請求支持。使用這種方法給了我很大的信心,我已經在我的測試中用一個等價的假請求覆蓋了我所有的出站請求。
HTTP 事件的日志處理程序
Laravel 的 HTTP 客戶端有很多有價值的事件,你可以用它們來快速挖掘請求/響應生命周期的重要階段。在寫這篇文章的時候,有三個事件被觸發:
- IlluminateHttpClientEventsRequestSending
- IlluminateHttpClientEventsResponseReceived
- IlluminateHttpClientEventsConnectionFailed
比方說,你想把你的應用程序發出請求的每個 URL 都可視化。我們可以很容易地接入 RequestSending 事件,并記錄出每個請求。
namespoace App/Listeners; use IlluminateContractsQueueShouldQueue; use IlluminateQueueInteractsWithQueue; use IlluminateSupportFacadesLog; class LogRequestSending { public function handle(object $event): void { Log::debug('HTTP請求正在發送。', ['url' => $event->request->url() 'url' => $event->request->url(), ]); } }
為了使事件處理程序工作,在 EventServiceProvider 類中添加以下內容。
use AppListenersLogRequestSending; use IlluminateHttpClientEventsRequestSending; // ... protected $listen = [ Registered::class => [ SendEmailVerificationNotification::class, ], RequestSending::class => [ LogRequestSending::class, ], ];
一旦它被連接起來,你就會在你的日志中看到類似于 HTTP 客戶端嘗試的每個請求的內容。
[2023-03-17 04:06:03] local.DEBUG: HTTP請求正在被發送。{"url": "https://api.example.com/v1/widget/123"}
了解更多
官方的示例有你需要的一切,可以開始了。我希望這個教程能給你一些靈感和技巧,你可以在你的 Laravel 應用程序中使用。
原文地址:示例
譯文地址:示例