PSR-18 HTTP клиент.

В этом документе описывается общий интерфейс для отправки HTTP-запросов и получения HTTP-ответов.

Данная статья, это авторский перевод, описания стандарта. С оригиналом описания Вы можете ознакомиться здесь.

Цель PSR-18

Цель этого PSR — позволить разработчикам создавать библиотеки, не связанные с реализациями HTTP-клиентов. Это сделает библиотеки более пригодными для повторного использования, поскольку уменьшит количество зависимостей и снизит вероятность конфликтов версий.

Вторая цель состоит в том, что HTTP-клиенты могут быть заменены в соответствии с принципом подстановки Барбары Лисков. Это означает, что все клиенты ДОЛЖНЫ вести себя одинаково при отправке запроса.

Определения, используемые в PSR-18.

  • Client — это библиотека, которая реализует эту спецификацию для отправки PSR-7-совместимых сообщений HTTP-запроса и возврата PSR-7-совместимого сообщения HTTP-ответа в вызывающую библиотеку.
  • Calling Library — это любой код приложения, использующий client. Он не реализует интерфейсы этой спецификации, но использует объекты, который реализует client.

Client.

Клиент — это объект, реализующий ClientInterface.

Клиент МОЖЕТ:

  1. Самостоятельно изменять и отправлять HTTP-запрос вместо того, который был предоставлен. Как пример, он может сжимать тело исходящего сообщения, для изменения размера.
  2. Самостоятельно изменять полученный HTTP-ответ перед его возвратом в вызывающую библиотеку. Например, он может клиент может распаковать тело входящего сообщения.

Так если клиент решит изменять HTTP-запрос или HTTP-ответ, он ДОЛЖЕН убедиться, что объект остается внутренне непротиворечивым. Для примера, если клиент решает распаковать тело сообщения, он ДОЛЖЕН также удалить заголовок Content-Encoding и скорректировать заголовок Content-Length.

Следует обратить внимание и помнить, что поскольку объекты PSR-7 являются неизменяемыми, calling library НЕ ДОЛЖНА предполагать, что объект, переданный в метод интерфейса клиента ClientInterface::sendRequest(), будет тем же самым объектом PHP, который фактически будет отправляться. Например, объект Request, возвращаемый возможным исключением, МОЖЕТ быть другим объектом, чем объект, переданный в sendRequest(), поэтому сравнение объектов по ссылке (===) невозможно.

 

Клиент ДОЛЖЕН:

  • Самостоятельно собирать и преобразовывать многоэтапный ответ HTTP 1xx, чтобы в calling library возвращался действительный ответ HTTP с кодом состояния 200 или выше.

 

Обработка ошибок.

Клиент НЕ ДОЛЖЕН обрабатывать правильно сформированный HTTP-запрос или HTTP-ответ как состояние ошибки. Например, коды состояния ответа в диапазоне 400 и 500 НЕ ДОЛЖНЫ вызывать исключение и ДОЛЖНЫ возвращаться в библиотеку вызовов в обычном порядке.

Клиент ДОЛЖЕН генерировать экземпляр «Psr\Http\Client\ClientExceptionInterface» тогда и только тогда, когда он вообще не может отправить HTTP-запрос или если HTTP-ответ не может быть проанализирован в объект ответа по PSR-7.

Если запрос не может быть отправлен из-за того, что сообщение запроса не является правильно сформированным HTTP-запросом или отсутствует какая-либо важная часть информации (например, хост или метод), клиент ДОЛЖЕН создать экземпляр «Psr\Http\Client\RequestExceptionInterface«.

Если запрос не может быть отправлен из-за сбоя сети любого рода, включая тайм-аут, клиент ДОЛЖЕН создать экземпляр «Psr\Http\Client\NetworkExceptionInterface«.

Клиенты МОГУТ генерировать более конкретные исключения, чем те, которые определены здесь (например, «TimeOutException» или «HostNotFoundException«), при условии, что они реализуют соответствующий интерфейс, определенный выше.

Интерфейсы для реализации.

ClientInterface

namespace Psr\Http\Client;

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

interface ClientInterface
{
    /**
     * Отправляет request PSR-7 и возвращает response PSR-7.
     *
     * @param RequestInterface $request
     *
     * @return ResponseInterface
     *
     * @throws \Psr\Http\Client\ClientExceptionInterface Если при обработке запроса возникает ошибка.
     */
    public function sendRequest(RequestInterface $request): ResponseInterface;
}

ClientExceptionInterface

namespace Psr\Http\Client;

/**
 * Каждое исключение, связанное с HTTP-клиентом, ДОЛЖНО реализовывать этот интерфейс.
 */
interface ClientExceptionInterface extends \Throwable
{
}

RequestExceptionInterface

namespace Psr\Http\Client;

use Psr\Http\Message\RequestInterface;

/**
  * Исключение для случаев, когда запрос не выполнен.
  *
  * Примеры:
  * - Запрос недействителен (например, отсутствует метод)
  * - Ошибки запроса во время выполнения (например, основной поток не доступен для поиска)
  */
interface RequestExceptionInterface extends ClientExceptionInterface
{
    /**
     * Returns the request.
     *
     * Объект запроса МОЖЕТ отличаться от объекта, переданного в ClientInterface::sendRequest(RequestInterface $request).
     *
     * @return RequestInterface
     */
    public function getRequest(): RequestInterface;
}

NetworkExceptionInterface

namespace Psr\Http\Client;

use Psr\Http\Message\RequestInterface;

/**
  * Генерируется, когда запрос не может быть выполнен из-за проблем с сетью.
  *
  * Нет объекта ответа, так как это исключение генерируется, когда ответ не получен.
  *
  * Пример: имя целевого хоста не может быть разрешено или соединение не установлено.
  */
interface NetworkExceptionInterface extends ClientExceptionInterface
{
    /**
     * Returns the request.
     *
     * Объект запроса МОЖЕТ отличаться от объекта, переданного в ClientInterface::sendRequest(RequestInterface $request).
     *
     * @return RequestInterface
     */
    public function getRequest(): RequestInterface;
}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *