1 回答

TA貢獻(xiàn)1906條經(jīng)驗(yàn) 獲得超10個(gè)贊
這是我的看法,主要基于嘗試幾種方法。
任何PSR-18 客戶端都會(huì)有一個(gè)必須遵守的接口。該接口本質(zhì)上只是一種方法 - sendRequest()
. 該方法將發(fā)送PSR-7 請(qǐng)求 并返回PSR-7 響應(yīng)。
請(qǐng)求中的大部分內(nèi)容將用于構(gòu)建 PSR-7 請(qǐng)求。這將在它sendRequest()
到達(dá)客戶之前放在一起。PSR-18 規(guī)范沒有定義的是客戶端的行為,比如是否遵循重定向。它確實(shí)指定在非 2XX 響應(yīng)的情況下不應(yīng)引發(fā)異常。
這可能看起來非常有限制,但這個(gè)客戶端是最后,它只關(guān)心請(qǐng)求的物理發(fā)送和響應(yīng)的捕獲。有關(guān)客戶端行為的所有其他內(nèi)容都可以內(nèi)置到 中間件中以擴(kuò)展該客戶端。
那么 PSR-18 中間件可以做什么呢?
它可以訪問原始 PSR-7 請(qǐng)求,因此可以讀取和更改請(qǐng)求。
它可以訪問 PSR-7 響應(yīng),因此它可以修改響應(yīng),并根據(jù)該響應(yīng)采取行動(dòng)。
它發(fā)出
sendRequest()
調(diào)用,因此可以應(yīng)用處理方式的邏輯,例如重試、跟隨重定向等。
PSR-18 規(guī)范沒有提到中間件,那么它會(huì)放在哪里呢?一種實(shí)現(xiàn)方式可能是裝飾器。裝飾器包裹基本 PSR-18 客戶端,添加功能,但會(huì)將自己呈現(xiàn)為 PSR-18 客戶端。這意味著可以在基本客戶端上分層多個(gè)裝飾器以添加您喜歡的任意數(shù)量的功能。
這是一個(gè) PSR-18 裝飾器的示例。這個(gè)裝飾器本質(zhì)上什么都不做,但提供了一個(gè)框架來放入邏輯。
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
class Psr18Decorator implements ClientInterface
{
// ClientInterface
protected $client;
// Instantiate with the current PSR-18 client.
// Options could be added here for configuring the decorator.
public function __construct(ClientInterface $client)
{
$this->client = $client;
}
public function sendRequest(RequestInterface $request): ResponseInterface
{
// The request can be processed here.
// Send the request, just once in this example.
$response = $this->client->sendRequest($request);
// The response can be processed or acted on here.
return $response;
}
// This is added so that if a decorator adds new methods,
// they can be accessed from the top, multiple layers deep.
public function __call($method, $parameters)
{
$result = $this->client->$method(...$parameters);
return $result === $this->client ? $this : $result;
}
}
所以給定基本的 PSR-18 客戶端,它可以這樣裝飾:
$decoratedPsr18Client = new Psr18Decorator($basePsr18Client);
可以編寫每個(gè)裝飾器來處理單個(gè)關(guān)注點(diǎn)。例如,如果響應(yīng)未返回 2XX 代碼,您可能希望拋出異常??梢跃帉懸粋€(gè)裝飾器來做到這一點(diǎn)。
另一個(gè)裝飾器可以處理 OAuth 令牌,或監(jiān)控對(duì) API 的訪問,因此可以對(duì)其進(jìn)行速率限制。另一個(gè)裝飾器可以跟隨重定向。
那么,您需要自己編寫所有這些裝飾器嗎?就目前而言,是的,因?yàn)椴恍业氖侵車狈λ鼈?。然而,由于它們是作為包開發(fā)和發(fā)布的,它們本質(zhì)上是可重用的代碼,可以應(yīng)用于任何 PSR-18 客戶端。
Guzzle 很棒,有很多功能,在這方面是單一的。我相信 PSR-18 方法應(yīng)該允許我們將所有這些功能分解成更小的獨(dú)立塊,以便可以根據(jù)需要應(yīng)用它們。裝飾器管理包可能有助于添加這些裝飾器(可能確保它們正確排序并相互兼容),并且可能以不同方式處理裝飾器自定義方法以避免需要__call()回退。
我敢肯定還有其他方法,但這個(gè)方法對(duì)我來說效果很好。
- 1 回答
- 0 關(guān)注
- 169 瀏覽
添加回答
舉報(bào)