RESTful API с расширением # фрагмента в шаблоне URI (RFC 6570)

У меня есть спецификация RESTful API для нового проекта от другой компании, и она относится к RFC6570 и использованию расширения фрагмента {#var} в шаблоне URI при выполнении запросов к их API.

Шаблоны URI выглядят так:

PUT https://api.acme.com/order{#meta*}{?order_number} или GET https://api.acme.com/orders{#meta*} (обратите внимание на разницу с заказом/заказами).

Они упоминают, «если метаданные, хранящиеся в вашей системе, выглядят так:»

{
  "meta": {
    "customer": "1234",
    "state": "open"
  },
  "order_number": "0003"
}

Затем это преобразуется в запросы типа PUT https://api.acme.com/order#customer=1234,state=open?order_number=0003 или GET https://api.acme.com/orders#customer=1234,state=open.

Фрагменты URL, например. #customer=1234,state=open предназначены для использования в качестве фильтрации метаданных или контекста для запроса?

Запросы почтальона, curl и браузера, по-видимому, удаляют все после # перед отправкой на сервер. Является ли это ожидаемым поведением и описано где-нибудь в RFC? Означает ли это, что эти URL-адреса RESTful недействительны?

Как правильно использовать расширение фрагмента {#var} в шаблонах URL?


person DLT    schedule 07.10.2020    source источник
comment
Мы обнаружили tools.ietf.org/html/rfc7230#section-5.1 в котором указано Целевой URI исключает компонент фрагмента ссылки, если он есть, поскольку идентификаторы фрагментов зарезервированы для обработки на стороне клиента и tools.ietf.org/html/rfc3986#section-3.5, в котором указано, что компонент запроса обозначается первым знаком вопроса (?) и завершается знаком номера (#). Я предполагаю, что это означает, что URL-адрес недействителен с точки зрения RFC, но все же хотел бы знать, имеет ли # Fragment Expansion какой-либо смысл в дизайне RESTful и/или каковы предполагаемые варианты использования.   -  person DLT    schedule 08.10.2020


Ответы (1)


Запросы почтальона, завитка и браузера, по-видимому, удаляют все после # перед отправкой на сервер. Является ли это ожидаемым поведением и описано где-нибудь в RFC?

Да, это описано в RFC 3896.

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

Та же идея, описанная в RFC 7230.


Означает ли это, что эти URL-адреса RESTful недействительны?

Вроде, как бы, что-то вроде.

https://api.acme.com/orders#customer=1234,state=open

Это абсолютно правильный URL (см. правила производства в RFC 3986, приложение A). .

Давайте рассмотрим спецификацию для фрагментов:

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

определение HTTP немного яснее:

Необязательный компонент фрагмента позволяет косвенно идентифицировать вторичный ресурс.

Так что для практики посмотрим на идентификатор самой спецификации фрагмента

https://tools.ietf.org/html/rfc3986#section-3.5

Здесь мы имеем идентификаторы для двух ресурсов: первичный ресурс — это сама веб-страница, которая определяется последовательностью символов перед разделителем фрагментов — https://tools.ietf.org/html ; тогда у нас есть вторичный ресурс внутри этого основного ресурса, section-3.5 говорит нам, что искать в первичном ресурсе. Таким образом, браузер знает, что нужно (а) загрузить первичный ресурс, а затем (б), обнаружив, что первичный ресурс имеет представление text/html, знает, как копаться в html-тегах, чтобы найти тег, соответствующий фрагменту. Затем браузер может перейти непосредственно к нужному месту в документе.

В вашем примере https://api.acme.com/orders является основным ресурсом, а customer=1234,state=open это фрагмент, используемый для идентификации некоторого ресурса в представлении первичного ресурса.

НО

RFC 7230 определяет строку запроса HTTP.

method SP request-target SP HTTP-version CRLF

Где запрос-цель, в свою очередь, определяется как

     request-target = origin-form
                    / absolute-form
                    / authority-form
                    / asterisk-form

Нас интересуют два из них: origin-form и абсолютная форма. Оба определены в RFC 7230.

origin-form    = absolute-path [ "?" query ]
absolute-form  = absolute-URI

где absolute-URI определен в RFC 3986.

Некоторые элементы протокола допускают только абсолютную форму URI без идентификатора фрагмента.

absolute-URI  = scheme ":" hier-part [ "?" query ]

Все это согласуется с ограничением на target-uri.

Целевой URI исключает компонент фрагмента ссылки, если таковой имеется, поскольку идентификаторы фрагментов зарезервированы для обработки на стороне клиента.


Как правильно использовать расширение фрагмента {#var} в шаблонах URL?

Попытка построить ссылку на вторичный ресурс, в частности, как совместную работу двух частей кода; одна часть кода знает значения для переменных шаблона, но не знает, куда они должны идти (и, в частности, какие переменные принадлежат фрагменту), а другая часть кода знает, где в URI предполагается каждая из различных переменных появиться, но не зная, каковы значения.

Другими словами, это точно то же самое, что мы делаем, когда создаем шаблон URI, чтобы разрешить создание идентификатора основного ресурса, но также разрешить расширение переменных в элементе фрагмента.

http://example.org/people/bob
http://example.org/people#bob
person VoiceOfUnreason    schedule 08.10.2020