Параметры матрицы URL по сравнениюпараметры запроса
-
20-09-2019 - |
Вопрос
Мне интересно, использовать ли matrix или параметры запроса в моих URL-адресах.Я нашел более старого Обсуждение к этой теме, не удовлетворяющей.
Примеры
- URL-адрес с параметрами запроса: http://some.where/thing?paramA=1 ¶мБ=6542
- URL-адрес с матричными параметрами: http://some.where/thing ;paramA=1;ParamB=6542
На первый взгляд кажется, что матричные параметры имеют только преимущества:
- более читабельный
- кодирование и декодирование "&" в XML-документах не требуется
- URL-адреса с "?" во многих случаях не кэшируются;URL-адреса с матричными параметрами кэшируются
- параметры матрицы могут появляться везде в пути и не ограничиваются его концом
- параметры матрицы могут иметь более одного значения:
paramA=val1,val2
Но есть и недостатки:
- только несколько фреймворков, таких как JAX-RS параметры матрицы поддержки
- Когда браузер отправляет форму через GET, параметры становятся параметрами запроса.Таким образом, в итоге получается два вида параметров для одной и той же задачи.Чтобы не сбивать с толку пользователей сервисов REST и ограничивать усилия разработчиков сервисов, было бы проще использовать always query params - в этой области.
Поскольку разработчик сервиса может выбрать фреймворк с поддержкой matrix param, единственным оставшимся недостатком будет то, что браузеры создают параметры запроса по умолчанию.
Есть ли какие-то другие недостатки?Что бы вы сделали?
Решение
Важное отличие заключается в том, что параметры матрицы применяются к конкретному элементу пути, в то время как параметры запроса применяются к запросу в целом.Это вступает в игру при выполнении сложного запроса в стиле REST к нескольким уровням ресурсов и подресурсов:
http://example.com/res/categories;name=foo/objects;name=green/?page=1
На самом деле все сводится к пространству имен.Если бы использовались только параметры запроса, вы бы в конечном итоге получили такие параметры, как "имя_категории" и "имя_объекта", и вы бы потеряли ясность, добавляемую локальностью параметров в запросе.Кроме того, при использовании фреймворка, подобного JAX-RS, все параметры запроса будут отображаться в каждом обработчике ресурсов, что приведет к потенциальным конфликтам и путанице.
Если ваш запрос имеет только один "уровень", то разница на самом деле не важна, и два типа параметров фактически взаимозаменяемы, однако параметры запроса, как правило, лучше поддерживаются и более широко распознаются.В общем, я бы рекомендовал вам придерживаться параметров запроса для таких вещей, как HTML-формы и простые одноуровневые HTTP-API.
Другие советы
--Слишком важный, чтобы его можно было перенести в раздел комментариев.--
Я не уверен, что такого особенного в матричных URL-адресах.Согласно статье о дизайне w3c, которую написала TBL, это была просто дизайнерская идея, и в ней прямо говорится, что это не особенность Интернета.Такие вещи, как относительные URL-адреса, не реализуются при его использовании.Если вы хотите им воспользоваться, это прекрасно;просто нет стандартного способа его использования, потому что это не стандарт.– Стив Померой
Итак, короткий ответ таков: если вам нужен RS для бизнес-целей, вам лучше использовать параметр запроса.
В дополнение к У Тима Сильвестра ответ Я хотел бы привести пример того, как параметры матрицы могут быть обработаны с JAX-RS .
Параметры матрицы в последнем элементе ресурса
http://localhost:8080/res/categories/objects;name=green
Вы можете получить к ним доступ с помощью
@MatrixParam
аннотация@GET @Path("categories/objects") public String objects(@MatrixParam("name") String objectName) { return objectName; }
Ответ
green
Но, как утверждает Javadoc,
Обратите внимание, что
@MatrixParam
значение аннотации ссылается на имя матричного параметра , который находится в последний согласованный сегмент пути структуры Java с аннотацией пути, которая вводит значение параметра matrix....что подводит нас к пункту 2
Параметры матрицы в середине URL-адреса
http://localhost:8080/res/categories;name=foo/objects;name=green
Вы можете получить доступ к параметрам матрицы в любом месте, используя переменные пути и
@PathParam
PathSegment
.@GET @Path("{categoryVar:categories}/objects") public String objectsByCategory(@PathParam("categoryVar") PathSegment categorySegment, @MatrixParam("name") String objectName) { MultivaluedMap<String, String> matrixParameters = categorySegment.getMatrixParameters(); String categorySegmentPath = categorySegment.getPath(); String string = String.format("object %s, path:%s, matrixParams:%s%n", objectName, categorySegmentPath, matrixParameters); return string; }
Ответ
object green, path:categories, matrixParams:[name=foo]
Поскольку параметры матрицы предоставляются в виде
MultivaluedMap
вы можете получить доступ к каждому из них с помощьюList<String> names = matrixParameters.get("name");
или если вам нужен только первый
String name = matrixParameters.getFirst("name");
Получить все параметры матрицы как один параметр метода
http://localhost:8080/res/categories;name=foo/objects;name=green//attributes;name=size
Используйте
List<PathSegment>
чтобы получить их все@GET @Path("all/{var:.+}") public String allSegments(@PathParam("var") List<PathSegment> pathSegments) { StringBuilder sb = new StringBuilder(); for (PathSegment pathSegment : pathSegments) { sb.append("path: "); sb.append(pathSegment.getPath()); sb.append(", matrix parameters "); sb.append(pathSegment.getMatrixParameters()); sb.append("<br/>"); } return sb.toString(); }
Ответ
path: categories, matrix parameters [name=foo] path: objects, matrix parameters [name=green] path: attributes, matrix parameters [name=size]