Параметры матрицы URL по сравнению с параметрами запроса
Мне интересно, следует ли использовать параметры матрицы или запроса в моих URL-адресах. Я нашел более старую дискуссию, чтобы эта тема не удовлетворяла.
Примеры
На первый взгляд матричные параметры кажутся только преимуществами:
- более читаемый
- нет кодирования и декодирования "&" в документах XML требуется
- URL с "?" во многих случаях не кэшируются; URL-адреса с матричными параметрами кэшируются
- параметры матрицы могут появляться повсюду в пути и не ограничены его концом
- Параметры матрицы могут иметь более одного значения:
paramA=val1,val2
Но есть и недостатки:
- только несколько фреймворков, таких как JAX-RS поддерживают параметры матрицы
- Когда браузер отправляет форму через GET, параметры становятся параметрами запроса. Таким образом, он заканчивается двумя параметрами для одной и той же задачи. Чтобы не путать пользователей служб REST и ограничить усилия для разработчиков этих сервисов, было бы проще использовать всегда параметры запроса - в этой области.
Поскольку разработчик службы может выбрать фреймворк с поддержкой матрицы param, единственным оставшимся недостатком будет то, что браузеры создают параметры запроса по умолчанию.
Есть ли другие недостатки? Что бы вы сделали?
Ответы
Ответ 1
Важное различие заключается в том, что параметры матрицы применяются к определенному элементу пути, а параметры запроса относятся к запросу в целом. Это вступает в игру при создании сложного запроса типа REST на несколько уровней ресурсов и под-ресурсов:
http://example.com/res/categories;name=foo/objects;name=green/?page=1
Это действительно сводится к пространству имен. Если бы использовались только параметры запроса, у вас были бы такие параметры, как "category_name" и "object_name", и вы потеряли бы ясность, добавленную местностью параметров в запросе. Кроме того, при использовании такой структуры, как JAX-RS, все параметры запроса будут отображаться внутри каждого обработчика ресурсов, что приведет к потенциальным конфликтам и путанице.
Если ваш запрос имеет только один "уровень", разница не очень важна, и два типа параметров эффективно взаимозаменяемы, однако параметры запроса обычно лучше поддерживаются и более широко распознаются. В общем, я бы рекомендовал вам придерживаться параметров запроса для таких вещей, как HTML-формы и простые одноуровневые HTTP-API.
Ответ 2
- Слишком важно отнести к разделу комментариев.--
Я не уверен, в чем дело с матричными URL-адресами. Согласно статье дизайна w3c, написанной TBL, она была просто дизайнерской идеей и явно заявляет, что она не является особенностью сети. Такие вещи, как относительные URL-адреса, не используются при его использовании. Если вы хотите использовать его, это хорошо; там просто нет стандартного способа использовать его, потому что это не стандарт. - Стив Померой
Итак, короткий ответ: если вам нужен RS для деловых целей, вам лучше использовать параметр запроса.
Ответ 3
В дополнение к типу Тима Сильвестра я хотел бы привести пример того, как параметры матрицы можно обрабатывать с помощью JAX-RS.
-
Параметры Matix в последнем элементе ресурса
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
аннотации @MatrixParam
ссылается на имя параметра матрицы, который находится в последнем сегменте согласованного пути структуры Java с контуром, который вводит значение параметра матрицы.
... что приводит нас к пункту 2
-
Матричные параметры в середине URL-адреса
http://localhost:8080/res/categories;name=foo/objects;name=green
Вы можете обращаться к параметрам матрицы в любом месте, используя переменные пути и @PathParam
PathSegment
.
@GET
@Path("{categoryVar:categories}/objects")
public String objectsByCatecory(@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]