Skip to content

Мета-документ определения ссылок

1. Краткое описание

Гипермедиа-ссылки становятся всё более важной частью веба — как в контексте HTML, так и в различных форматах API. Однако не существует единого общепринятого формата гипермедиа и единого способа представления ссылок между форматами.

Данная спецификация ставит целью предоставить PHP-разработчикам простой и универсальный способ представления гипермедиа-ссылки независимо от используемого формата сериализации. Это, в свою очередь, позволяет системе сериализовать ответ с гипермедиа-ссылками в один или несколько проводных форматов независимо от процесса принятия решения о том, какими эти ссылки должны быть.

2. Область применения

2.1 Цели

  • Данная спецификация ставит целью извлечь и стандартизировать представление гипермедиа-ссылок между различными форматами.

2.2 Вне области применения

  • Данная спецификация не ставит целью стандартизировать или отдавать предпочтение какому-либо конкретному формату сериализации гипермедиа.

3. Принятые проектные решения

Почему нет методов-мутаторов?

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

Кроме того, некоторые объекты провайдера ссылок могут не быть объектами-значениями, а представлять другие объекты в рамках некоторой предметной области, способные динамически генерировать ссылки, например на основе результатов запроса к базе данных или иного нижележащего представления. В таких случаях определение записываемого провайдера было бы несовместимо.

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

Почему отношение ссылки является многозначным?

Различные стандарты гипермедиа по-разному обрабатывают несколько ссылок с одним и тем же отношением. В одних стандартах используется одна ссылка с несколькими определёнными отношениями. В других — одна запись отношения, содержащая несколько ссылок.

Определение каждой ссылки как уникальной, но с возможностью иметь несколько отношений, обеспечивает определение с наибольшей совместимостью. Один объект LinkInterface может быть сериализован в одну или несколько записей ссылок в данном формате гипермедиа, в зависимости от ситуации. Однако указание нескольких объектов ссылок с одним отношением, но одним и тем же URI также допустимо, и формат гипермедиа может сериализовать это соответствующим образом.

Зачем нужен LinkProviderInterface?

Во многих контекстах набор ссылок прикрепляется к некоторому другому объекту. Эти объекты могут использоваться в ситуациях, когда значимы лишь их ссылки или некоторое их подмножество. Например, могут быть определены различные объекты-значения, представляющие разные REST-форматы, такие как HAL, JSON-LD или Atom. Может оказаться полезным единообразно извлекать ссылки из такого объекта для дальнейшей обработки. Например, ссылки «следующий/предыдущий» могут быть извлечены из объекта и добавлены в объект PSR-7 Response в качестве заголовков Link. Кроме того, многие ссылки имеет смысл представлять с отношением ссылки «preload», что указывало бы HTTP/2-совместимому веб-серверу на необходимость передать связанные ресурсы клиенту заранее, в ожидании последующего запроса.

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

4. Участники

4.1 Редактор(ы)

  • Larry Garfield

4.2 Спонсоры

  • Matthew Weier O'Phinney (координатор)
  • Marc Alexander

4.3 Участники

  • Evert Pot

5. Голосование

6. Релевантные ссылки

7. Исправления и уточнения

7.1 Добавление типов

Версия 1.1 пакета psr/link включает скалярные типы параметров. Версия 2.0 пакета включает типы возвращаемых значений. Эта структура использует поддержку ковариантности PHP 7.2 для постепенного процесса обновления, однако требует PHP 8.0 для полной совместимости типов.

Разработчики реализаций МОГУТ добавлять типы возвращаемых значений в свои пакеты по собственному усмотрению при условии, что:

  • типы возвращаемых значений совпадают с типами в пакете версии 2.0;
  • реализация указывает минимальную версию PHP 8.0.0 или выше.

Разработчики реализаций МОГУТ добавлять типы параметров в свои пакеты в новом мажорном релизе — одновременно с добавлением типов возвращаемых значений или в последующем релизе — при условии, что:

  • типы параметров совпадают с типами в пакете версии 1.1;
  • реализация указывает минимальную версию PHP 8.0.0 или выше;
  • реализация зависит от "psr/link": "^1.1 || ^2.0", чтобы исключить нетипизированную версию 1.0.

Разработчикам реализаций рекомендуется, но не требуется при первой возможности перевести свои пакеты на версию 2.0 пакета.

7.2 Обработка типов атрибутов

Исходная спецификация содержала несоответствие в отношении значений-массивов для атрибутов. В тексте спецификации в разделе 1.2 указывалось, что значения атрибутов (передаваемые в EvolvableLinkInterface::withAttribute()) могут быть нескольких типов, некоторые из которых допускают особую обработку (например, булевы значения или массивы). Однако в docblock этого метода было указано, что параметр $value должен быть строкой, что являлось некорректным.

Для устранения данного несоответствия интерфейс был исправлен в более поздних версиях: теперь $value может быть типа string|\Stringable|int|float|bool|array. Разработчики реализаций СЛЕДУЕТ обрабатывать объект Stringable так же, как параметр типа string. Разработчики реализаций МОГУТ сериализовывать int, float или bool альтернативными, типо-осознанными способами для конкретного формата сериализации, если это уместно. Прочие типы объектов и ресурсы по-прежнему недопустимы.

Множественные вызовы withAttribute() с одним и тем же $name ДОЛЖНЫ перезаписывать ранее предоставленные значения, как уже указано в спецификации. Чтобы передать несколько значений для конкретного атрибута, следует передать массив с нужными значениями.

Все прочие правила и требования раздела 1.2 остаются в силе.