Skip to content

Мета-документ HTTP-клиента

Краткое содержание

HTTP-запросы и ответы — два фундаментальных объекта веб-программирования. Все клиенты, взаимодействующие с внешним API, используют ту или иную форму HTTP-клиента. Многие библиотеки связаны с одним конкретным клиентом или сами реализуют уровень клиента и/или адаптера. Это приводит к плохому проектированию библиотеки, конфликтам версий или коду, не связанному с доменом библиотеки.

О чем речь?

Благодаря PSR-7 мы знаем, как в идеале выглядят HTTP-запросы и ответы, но ничто не определяет, как должен быть отправлен запрос и получен ответ. Общий интерфейс для HTTP-клиентов позволит отделить библиотеки от конкретных реализаций.

Суть

Цели

  • Общий интерфейс для отправки сообщений PSR-7 и возврата ответов PSR-7.

Не является целью

  • Поддержка асинхронных HTTP-запросов оставлена для следующего будущего PSR.
  • Этот PSR не определяет, как настроить HTTP-клиент. Он определяет только поведение по умолчанию.
  • Этот PSR нейтрален в отношении использования промежуточного программного обеспечения.

Асинхронный HTTP-клиент

Причина, по которой асинхронные запросы не охватываются этим PSR, заключается в отсутствии общего стандарта для промисов. Промисы достаточно сложны, поэтому заслуживают отдельной спецификации, и их не следует включать в эту спецификацию.

Отдельный интерфейс для асинхронных запросов можно определить в отдельном PSR после принятия Promise PSR. Сигнатура метода для асинхронных запросов ДОЛЖНА отличаться от сигнатуры метода для синхронных запросов, поскольку типом возврата асинхронных вызовов будет обещание. Таким образом, этот PSR совместим с прямой совместимостью, и клиенты смогут реализовать один или оба интерфейса в зависимости от функций, которые они хотят предоставить.

Подходы

Поведение по умолчанию

Цель этого PSR — предоставить разработчикам библиотек HTTP-клиенты с четко определенным поведением. Библиотека должна иметь возможность использовать любой совместимый клиент без специального кода для обработки деталей реализации клиента (принцип замены Лискова). PSR не пытается ограничивать или определять способ настройки HTTP-клиентов.

Альтернативный подход — передать конфигурацию клиенту. Такой подход будет иметь несколько недостатков:

  • Конфигурация должна быть определена PSR.
  • Все клиенты должны поддерживать определенную конфигурацию.
  • Если клиенту не передается никакая конфигурация, поведение будет непредсказуемым.

Обоснование названия

Основное поведение интерфейса определяется методом sendRequest(RequestInterface $request): ResponseInterface. Хотя было предложено более короткое имя метода send(), оно уже использовалось существующими и очень распространенными HTTP-клиентами, такими как Guzzle. Таким образом, если они собираются принять этот стандарт, им, возможно, придется нарушить обратную совместимость, чтобы реализовать спецификацию. Определив вместо этого sendRequest(), мы гарантируем, что они могут быть приняты без каких-либо немедленных перерывов в BC.

Модель исключений

Исключения домена NetworkExceptionInterface и RequestExceptionInterface определяют контракт, очень похожий друг на друга. Выбранный подход состоит в том, чтобы не позволять им расширять друг друга, поскольку наследование не имеет смысла в модели предметной области. RequestExceptionInterface — это просто не NetworkExceptionInterface.

Разрешение исключений для расширения интерфейса RequestAwareException и/или ResponseAwareException обсуждалось, но это удобный ярлык, который не следует использовать. Лучше перехватывать конкретные исключения и обрабатывать их соответствующим образом.

Можно было бы быть более детальным при определении исключений. Например, TimeOutException и HostNotFoundException могут быть подтипами NetworkExceptionInterface. Выбранный подход заключается в том, чтобы не определять такие подтипы, поскольку обработка исключений в потребляющей библиотеке в большинстве случаев не будет различаться между этими исключениями.

Выдача исключений для ответов 4xx и 5xx

Первоначальная идея заключалась в том, чтобы позволить клиенту настроить выдачу исключений для ответов со статусом HTTP 4xx и 5xx. Такой подход нежелателен, поскольку потребляющим библиотекам придется проверять ответы 4xx и 5xx дважды: во-первых, путем проверки кода состояния в ответе, а во-вторых, путем перехвата потенциальных исключений.

Чтобы сделать спецификацию более предсказуемой, было решено, что HTTP-клиенты никогда не будут генерировать исключения для ответов 4xx и 5xx.

Промежуточное программное обеспечение и упаковка клиента

Спецификация не накладывает никаких ограничений на промежуточное программное обеспечение или классы, которые хотят обернуть/украсить HTTP-клиент. Если класс оформления также реализует ClientInterface, он также должен соответствовать спецификации.

Соблазнительно разрешить настройку или добавить промежуточное программное обеспечение к HTTP-клиенту, чтобы он мог, например, следовать перенаправлениям или генерировать исключения. Если это решение разработчика приложения, то он прямо заявил, что хочет нарушить спецификацию. Это проблема (или функция), которую должен решить разработчик приложения. Сторонние библиотеки НЕ ДОЛЖНЫ предполагать, что HTTP-клиент нарушает спецификацию.

Бэкграунд

HTTP-клиент PSR был вдохновлен и создан командой php-http. Еще в 2015 году они создали HTTPlug как общий интерфейс для HTTP-клиентов. Им нужна была абстракция, которую могли бы использовать сторонние библиотеки, чтобы не полагаться на конкретную реализацию HTTP-клиента. Стабильная версия была выпущена в январе 2016 года, и с тех пор проект получил широкое распространение. Поскольку за два года после выхода первоначальной стабильной версии было скачано более 3 миллионов раз, пришло время преобразовать этот «де-факто» стандарт в официальную спецификацию.

Люди

5.1 Редактор

  • Tobias Nyholm

5.2 Спонсоры

  • Sara Golemon

5.3 Рабочая группа

  • Simon Asika (Windwalker)
  • David Buchmann (HTTPlug)
  • David De Boer (HTTPlug)
  • Sara Golemon (Sponsor)
  • Jeremy Lindblom (Guzzle)
  • Christian Lück (Buzz react)
  • Tobias Nyholm (Editor)
  • Matthew Weier O'Phinney (Zend)
  • Mark Sagi-Kazar (Guzzle)
  • Joel Wurtz (HTTPlug)

Голоса

Предлагаемые реализации

Ниже приведены две реализации, предоставленные рабочей группой для прохождения периода проверки:

  • HTTPlug подготовил версию 2.0, чтобы убедиться, что она поддерживает новый PSR. Они просто ждут выхода PSR: https://github.com/php-http/httplug/tree/2.x
  • Buzz адаптируется к каждой версии PSR и выпустил версию 0.17.3 с последней версией psr/http-client: https://github.com/kriswallsmith/Buzz.