侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

在laravel框架中的5个HTTP客户端技巧分享

Laravel  /  管理员 发布于 2年前   491

作为网络开发者, 我们经常需要与Laravel应用程序的API进行交互. Laravel HTTP客户端,在第7版中引入,为Guzzle HTTP库提供了一个方便和直观的包装。

在这篇文章中, 我们将探讨五个有价值的技巧来使用Laravel HTTP客户端, 这些技巧可以使你的开发经验更加高效和愉快.


这些技巧包括使用HTTP宏,为容器服务配置HTTP客户端,可移植的基本URL配置,防止测试中的杂散请求,以及监听HTTP事件。

通过掌握这些技巧, 你可以简化你的API交互, 并创建更强大和可维护的Laravel应用程序.


HTTP宏

许多Laravel的服务有一个 "宏 "的功能,允许你为你的应用程序定义自定义方法。

而不是从Laravel框架中扩展核心类,你可以将这些宏添加到服务提供者的boot()方法中。


HTTP文档显示了一个宏的例子

https://laravel.com/docs/10.x/http-client#macros

你可以用它来定义常见的设置:

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包含了一个尾部的/,因为根据RFC 3986,它在我的选项中提供了最大的可移植性。

以下面的服务配置为例(注意默认的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/;

使用尾部斜线可以使URLs按预期工作,而不需要修改代码。

在配置尾部/的同时,注意我代码中所有的API调用都使用相对路径:

$this->client
    ->withUrlParameters(['uid' => $uid])
    // Example:
    // Staging - https://stg-api.example.com/widget/123
    // Production - https://api.example.com/v1/widget/123
    ->get('widget/{uid}');

请参阅Guzzle的创建客户端文档,看看不同的base_uri风格如何影响URI的解析。

https://docs.guzzlephp.org/en/stable/quickstart.html#creating-a-client


防止测试中的杂散请求

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 Illuminate\Foundation\Testing\TestCase as BaseTestCase;
use Illuminate\Support\Facades\Http;
 
abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;
 
    public function setUp(): void
    {
        parent::setUp();
 
        Http::preventStrayRequests();
    }
}

这样做将确保你的测试套件中触发的每个HTTP客户端调用都有一个假的请求支持。

使用这种方法让我信心大增,因为我的测试中所有的出站请求都有一个等价的假请求。


HTTP事件的日志处理程序

Laravel的HTTP客户端有很多有价值的事件,你可以用它们来快速进入请求/响应生命周期的重要阶段。

在写这篇文章的时候, 有三个事件被触发:

Illuminate\Http\Client\Events\RequestSending
Illuminate\Http\Client\Events\ResponseReceived
Illuminate\Http\Client\Events\ConnectionFailed

比方说,你想把你的应用程序发出请求的每个URL可视化。

我们可以很容易地接入RequestSending事件,并记录出每个请求:

namespace App\Listeners;
 
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;
 
class LogRequestSending
{
    public function handle(object $event): void
    {
        Log::debug('HTTP request is being sent.', [
            'url' => $event->request->url(),
        ]);
    }
}

为了使事件处理程序工作,在EventServiceProvider类中添加以下内容。

use App\Listeners\LogRequestSending;
use Illuminate\Http\Client\Events\RequestSending;
// ...
protected $listen = [
    Registered::class => [
        SendEmailVerificationNotification::class,
    ],
    RequestSending::class => [
        LogRequestSending::class,
    ],
];

一旦它被连接起来,你就会在你的日志中看到类似于HTTP客户端尝试的每个请求的内容:

[2023-03-17 04:06:03] local.DEBUG: HTTP request is being sent. {"url":"https://api.example.com/v1/widget/123"}


了解更多

官方的Laravel HTTP文档有你所需要的一切来开始。

https://laravel.com/docs/10.x/http-client

我希望这个教程能给你一些灵感和技巧, 你可以在你的Laravel应用程序中使用.


转:

https://laravel-news.com/laravel-http-client-tips

  • 上一条:
    在go语言中使用FFmpeg库实现PCM音频文件编码为mp3格式文件流程步骤
    下一条:
    nginx + vue配置实现同域名下不同路径访问不同项目
  • 昵称:

    邮箱:

    1条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • Laravel 11.14版本发布 - 新的字符串助手和ServeCommand改进(0个评论)
    • Laravel 11.12版本发布 - Artisan的`make`命令自动剪切`.php `扩展(0个评论)
    • Laravel的轻量型购物车扩展包:binafy/laravel-cart(0个评论)
    • Laravel 11.11版本发布 - 查看模型中的第三方关系:show(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-01
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客