PSR-18:HTTP客户端

HTTP客户端

本文档描述了用于发送HTTP请求和接收HTTP响应的通用接口。

本文件中的关键词“必须”,“不得”,“必须”,“应该”,“不应该”,“应该”,“不应该”,“推荐”,“可以”和“可选”按照RFC 2119中的描述进行解释

目标

此PSR的目标是允许开发人员创建与HTTP客户端实现分离的库。这将使库更可重用,因为它减少了依赖项的数量并降低了版本冲突的可能性。

第二个目标是可以根据Liskov替换原则替换HTTP客户端 这意味着所有客户端在发送请求时必须以相同的方式运行。

定义

  • 客户端 - 客户端是实现此规范的库,用于发送与PSR-7兼容的HTTP请求消息并将与PSR-7兼容的HTTP响应消息返回到呼叫库。
  • 调用库 - 调用库是使用客户端的任何代码。它没有实现此规范的接口,而是使用实现它们的对象(客户端)。

客户

客户端是实现的对象ClientInterface

客户可以:

  • 选择从提供的HTTP请求发送更改的HTTP请求。例如,它可以压缩传出消息体。
  • 选择在将收到的HTTP响应返回到调用库之前更改它。例如,它可以解压缩传入的消息体。

如果客户端选择更改HTTP请求或HTTP响应,则必须确保对象保持内部一致。例如,如果客户端选择解压缩消息体,那么它还必须删除Content-Encoding标头并调整Content-Length标头。

请注意,因此,由于PSR-7对象是不可变的,因此调用库绝不能假定传递给的ClientInterface::sendRequest()对象将是实际发送的相同PHP对象。例如,异常返回的Request对象可能与传递给它的对象不同sendRequest(),因此无法通过引用(===)进行比较。

客户必须:

  • 重新组合多步HTTP 1xx响应本身,以便返回到调用库的是状态代码200或更高的有效HTTP响应。

错误处理

客户端绝不能将格式正确的HTTP请求或HTTP响应视为错误条件。例如,400和500范围内的响应状态代码绝不能导致异常,必须正常返回到调用库。

客户端必须抛出Psr\Http\Client\ClientExceptionInterfaceif 的实例,并且只有当它根本无法发送HTTP请求或者无法将HTTP响应解析为PSR-7响应对象时。

如果由于请求消息不是格式正确的HTTP请求或者缺少某些关键信息(例如主机或方法)而无法发送请求,则客户端必须抛出一个实例Psr\Http\Client\RequestExceptionInterface

如果由于任何类型的网络故障(包括超时)而无法发送请求,则客户端必须抛出一个实例Psr\Http\Client\NetworkExceptionInterface

客户端可能会丢比这里定义的(更具体的例外TimeOutExceptionHostNotFoundException例如),只要它们实现上述定义的适当的接口。

接口

ClientInterface

namespace Psr\Http\Client;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

interface ClientInterface
{
    /**
     * Sends a PSR-7 request and returns a PSR-7 response.
     *
     * @param RequestInterface $request
     *
     * @return ResponseInterface
     *
     * @throws \Psr\Http\Client\ClientExceptionInterface If an error happens while processing the request.
     */
    public function sendRequest(RequestInterface $request): ResponseInterface;
}

ClientExceptionInterface

namespace Psr\Http\Client;

/**
 * Every HTTP client related exception MUST implement this interface.
 */
interface ClientExceptionInterface extends \Throwable
{
}

RequestExceptionInterface

namespace Psr\Http\Client;

use Psr\Http\Message\RequestInterface;

/**
 * Exception for when a request failed.
 *
 * Examples:
 *      - Request is invalid (e.g. method is missing)
 *      - Runtime request errors (e.g. the body stream is not seekable)
 */
interface RequestExceptionInterface extends ClientExceptionInterface
{
    /**
     * Returns the request.
     *
     * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
     *
     * @return RequestInterface
     */
    public function getRequest(): RequestInterface;
}

NetworkExceptionInterface

namespace Psr\Http\Client;

use Psr\Http\Message\RequestInterface;

/**
 * Thrown when the request cannot be completed because of network issues.
 *
 * There is no response object as this exception is thrown when no response has been received.
 *
 * Example: the target host name can not be resolved or the connection failed.
 */
interface NetworkExceptionInterface extends ClientExceptionInterface
{
    /**
     * Returns the request.
     *
     * The request object MAY be a different object from the one passed to ClientInterface::sendRequest()
     *
     * @return RequestInterface
     */
    public function getRequest(): RequestInterface;
}