innmind/http-transport

用于完成HTTP请求的库

7.3.0 2024-07-17 15:10 UTC

README

Build Status codecov Type Coverage

此库允许您发送http请求。

重要:为了正确使用此库,您必须使用vimeo/psalm

安装

composer require innmind/http-transport

用法

发送请求

use Innmind\HttpTransport\Curl;
use Innmind\TimeContinuum\Earth\Clock;
use Innmind\Http\Request;

$fulfill = Curl::of(new Clock);

$either = $fulfill(
    Request::of(/* initialize your request */),
);

2xx响应将在$either的右侧,所有错误和其他类型的响应将在左侧。

重要:您必须调用返回的Either上的match,否则请求将不会发送,但在调用match之前,您仍然可以在Either上调用其他方法。

并发性

默认情况下,没有对Curl传输并发性的限制。但如果你在解包结果之前调用了很多请求,你可能想如下配置最大并发性。

use Innmind\HttpTransport\Curl;
use Innmind\Http\{
    Request,
    Response,
    Method,
    ProtocolVersion,
};
use Innmind\Url\Url;
use Innmind\Immutable\Sequence;

$fulfill = Curl::of(new Clock)->maxConcurrency(5);
$responses = Sequence::of(
    'https://github.com/user/repo-a',
    'https://github.com/user/repo-b',
    'https://github.com/user/repo-c',
    // etc...
)
    ->map(static fn($url) => Request::of(
        Url::of($url),
        Method::get,
        ProtocolVersion::v20,
    ))
    ->map($fulfill)
    ->flatMap(static fn($either) => $either->match(
        static fn($success) => Sequence::of($success->response()),
        static fn() => Sequence::of(), // discard errors
    ))
    ->toList();
$responses; // list<Response>

假设你有100个URL要获取,将不会有超过5个请求并行进行。

记录请求

您可以轻松记录所有请求,如下所示

use Innmind\HttpTransport\Logger
use Psr\Log\LoggerInterface;

$fulfill = Logger::psr(/* an instance of Transport */, /* an instance of LoggerInterface */)

$fulfill(/* your request */);

在此,在请求发送之前记录了一条消息,一旦发送就记录了另一条。

指数退避

有时当调用外部API时,它可能因为负载过重而不可用。在这种情况下,您可以在API恢复一段时间后重试HTTP调用。您可以像这样应用此模式

use Innmind\HttpTransport\ExponentialBackoff;
use Innmind\TimeWarp\Halt\Usleep;

$fulfill = ExponentialBackoff::of(
    /* an instance of Transport */,
    new Usleep,
);

$fulfill(/* your request */);

默认情况下,如果服务器不可用,它将重试5次请求,每个调用之间遵循给定的时间间隔(以毫秒为单位):10027173820085459

熔断器

当调用某个域失败时,您可能希望立即使对该域的进一步调用失败,因为您知道这意味着主机已关闭。这种模式称为熔断器。

use Innmind\HttpTransport\CircuitBreaker;
use Innmind\TimeContinuum\Earth\{
    Clock,
    Period\Minute,
};

$fulfill = CircuitBreaker::of(
    /* an instance of CircuitBreaker */,
    new Clock,
    new Minute(10),
);

$fulfill(/* your request */);

如果调用导致服务器错误,此代码将为给定域打开10分钟的熔断器,在此延迟后,传输将允许新的请求通过,好像什么都没发生。

遵循重定向

默认情况下,传输不遵循重定向,以便您完全控制要执行的操作。但您可以用FollowRedirections包装您的传输,如下所示

use Innmind\HttpTransport\FollowRedirections;

$fulfill = FollowRedirections::of(/* an instance of Transport */);

$fulfill(/* your request */);

为了避免无限循环,它将遵循最多5次连续的重定向。

重要:根据rfc中的定义,使用方法不是GETHEAD的请求,当结果重定向到带有代码301302307308时,将不会重定向。您需要根据需要实现重定向,以确保此类重定向是安全的。