— y2sunlight 2020-07-28
本章は、若干の補足を加筆してはいるものの単にPSRのサイトを日本語に翻訳したものに過ぎません。英語が堪能な方は原文をご参照下さい。翻訳に当たっては、基本的に機械翻訳を使い、理解できない部分は独断で意訳しております。拙い訳では御座いますが恥を忍んで投稿しておりますので、ご指摘など御座いましたらコメントを頂ければ幸いです。
関連記事
— 原文より翻訳 PSR-18: HTTP Client 2020-08-25 現在
このドキュメントでは、HTTPリクエストを送信し、HTTPレスポンスを受信するための一般的なインターフェースについて説明します。
このドキュメントのキーワード MUST
, MUST NOT
, REQUIRED
, SHALL
, SHALL NOT
, SHOULD
, SHOULD NOT
, RECOMMENDED
, MAY
及び OPTIONAL
は、 RFC 2119で説明されているように解釈して下さい。
RFC 2119の説明
MUST
,REQUIRED
,SHALL
— 絶対必要
MUST NOT
,SHALL NOT
— 絶対禁止
SHOULD
,RECOMMENDED
— 推奨(但し、無視できる特定の正当な理由が存在するかもしれない)
SHOULD NOT
— 推奨できない(但し、許可できる特定の正当な理由が存在するかもしれない)
MAY
,OPTIONAL
— オプション
このPSRの目標は、開発者がHTTPクライアントの実装から分離されたライブラリを作成できるようにすることです。これにより、依存関係の数が減り、バージョンの競合の可能性が低くなるため、ライブラリの再利用性が高まります。
2番目の目標は、リスコフの置換原理に従ってHTTPクライアントを置き換えることができることです。これは、リクエストを送信するときに全てのクライアントが同じように動作する必要があること( MUST
)を意味します。
クライアント
— クライアント
は、PSR-7互換のHTTPリクエストメッセージを送信し、PSR-7互換のHTTPレスポンスメッセージを呼び出し側ライブラリに返す目的でこの仕様を実装するライブラリです。クライアント
を利用するコードで、この仕様のインターフェースは実装していませんが、それらを実装するオブジェクト(HTTPクライアント
)を使用しています。
クライアントは、ClientInterface
を実装するオブジェクトです。
クライアントの選択( MAY
):
MAY
)。例えば、送信メッセージの本文を圧縮できます。MAY
)。例えば、受信メッセージの本文を解凍できます。
クライアントがHTTPリクエストまたはHTTPレスポンスのいずれかを変更することを選択した場合、オブジェクトが内部的に一貫していることを保証する必要があります( MUST
)。例えば、クライアントがメッセージ本文を解凍することを選択した場合は、Content-Encoding
ヘッダーも削除して、Content-Length
ヘッダーを調整する必要があります。
その結果、PSR-7オブジェクトは不変であるため、呼び出し側ライブラリは、ClientInterface::sendRequest()
に渡されたオブジェクトが実際に送信されるPHPオブジェクトと同じであることを想定してはなりません。例えば、例外によって返されるRequestオブジェクトは、sendRequest()
に渡されるオブジェクトとは異なるオブジェクトになる可能性があるため、参照による比較( ===
)はできません。
クライアントの義務( MUST
):
MUST
)。
クライアントは、整形式のHTTPリクエストまたはHTTPレスポンスをエラー状態として扱わないでください( MUST NOT
)。例えば、400と500の範囲のレスポンスステータスコードは例外を発生させてはならず( MUST NOT
)、通常どおり呼び出しライブラリに返される必要があります( MUST
)。
クライアントは、HTTPリクエストをまったく送信できない場合、または HTTPレスポンスを PSR-7 レスポンスオブジェクトにパースできなかった場合にのみ、Psr\Http\Client\ClientExceptionInterface
のインスタンスをスローする必要があります( MUST
)。
リクエストメッセージが整形式のHTTPリクエストではないか、重要な情報(ホストやメソッドなど)がないためにリクエストを送信できない場合、クライアントは Psr\Http\Client\RequestExceptionInterface
のインスタンスをスローする必要があります( MUST
)。
タイムアウトを含むあらゆる種類のネットワーク障害が原因でリクエストを送信できない場合、クライアントは Psr\Http\Client\NetworkExceptionInterface
のインスタンスをスローする必要があります( MUST
)。
クライアントは、上記で定義された適切なインターフェースを実装している場合、ここで定義されたものよりも具体的な例外(例えば、 TimeOutException
または HostNotFoundException
)をスローできます( MAY
)。
namespace Psr\Http\Client; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; interface ClientInterface { /** * PSR-7リクエストを送信し、PSR-7レスポンスを返します。 * * @param RequestInterface $request * @return ResponseInterface * * @throws \Psr\Http\Client\ClientExceptionInterface リクエストの処理中にエラーが発生した場合。 * */ public function sendRequest(RequestInterface $request): ResponseInterface; }
namespace Psr\Http\Client; /** * すべてのHTTPクライアント関連の例外は、このインターフェイスを実装する必要があります。 */ interface ClientExceptionInterface extends \Throwable { }
namespace Psr\Http\Client; use Psr\Http\Message\RequestInterface; /** * リクエストが失敗した場合の例外。 * * 例: * -リクエストが無効です(メソッドが見つからないなど) * -ランタイムリクエストエラー(ボディストリームがシークできないなど) */ interface RequestExceptionInterface extends ClientExceptionInterface { /** * リクエストを返します。 * * リクエストオブジェクトは、ClientInterface::sendRequest()に渡されるオブジェクトとは * 異なるオブジェクトである可能性があります * * @return RequestInterface */ public function getRequest(): RequestInterface; }
namespace Psr\Http\Client; use Psr\Http\Message\RequestInterface; /** * ネットワークの問題のためにリクエストを完了できない場合にスローされます。 * * この例外は、応答が受信されなかった場合にスローされるため、応答オブジェクトはありません。 * * 例:ターゲットホスト名を解決できないか、接続が失敗しました。 */ interface NetworkExceptionInterface extends ClientExceptionInterface { /** * Returns the request. * * リクエストオブジェクトは、ClientInterface::sendRequest()に渡されるオブジェクトとは * 異なるオブジェクトである可能性があります * * @return RequestInterface */ public function getRequest(): RequestInterface; }