Параметры матрицы URL и параметры запроса

176

Мне интересно, использовать ли матрицу или параметры запроса в моих URL. Я нашел старое обсуждение этой темы не удовлетворяющим.

Примеры

На первый взгляд, матричные параметры имеют только преимущества:

  • более читаемый
  • не требуется кодирование и декодирование «&» в XML-документах
  • URL с "?" не кэшируются во многих случаях; URL-адреса с матричными параметрами кэшируются
  • Параметры матрицы могут появляться повсюду в пути и не ограничиваются его концом.
  • Параметры матрицы могут иметь более одного значения: paramA=val1,val2

Но есть и недостатки:

  • только несколько платформ, таких как JAX-RS, поддерживают параметры матрицы
  • Когда браузер отправляет форму через GET, параметры становятся параметрами запроса. Таким образом, это заканчивается двумя типами параметров для одной и той же задачи. Чтобы не запутывать пользователей сервисов REST и ограничивать усилия разработчиков сервисов, было бы проще всегда использовать параметры запроса - в этой области.

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

Есть ли другие недостатки? Что бы вы сделали?

Deamon
источник
10
Я не уверен, в чём дело с матричными URL. Согласно статье о дизайне w3c, написанной TBL, это была просто идея дизайна, в которой прямо говорится, что это не особенность сети. Такие вещи, как относительные URL-адреса, не используются при его использовании. Если вы хотите использовать это, это нормально; просто нет стандартного способа его использования, потому что это не стандарт.
Стив Померой
2
@Steve Pomeroy: Вы упоминаете эту статью: w3.org/DesignIssues/MatrixURIs.html
Марсель
3
@ Марсел: ага. Для тех, кто думает о матричных URL, обратите внимание на «Статус: личное представление» в верхней части документа.
Стив Померой
могут ли параметры матрицы иметь более одного значения? действительно?
Ayyash

Ответы:

212

Важным отличием является то, что параметры матрицы применяются к конкретному элементу пути, а параметры запроса применяются к запросу в целом. Это вступает в игру при создании сложного запроса в стиле REST для нескольких уровней ресурсов и подресурсов:

http://example.com/res/categories;name=foo/objects;name=green/?page=1

Это действительно сводится к пространству имен.

Примечание: «уровни» ресурсов здесь categoriesи objects.

Если бы для многоуровневого URL использовались только параметры запроса, вы бы получили

http://example.com/res?categories_name=foo&objects_name=green&page=1

Таким образом, вы также потеряете ясность, добавленную локальностью параметров в запросе. Кроме того, при использовании инфраструктуры, такой как JAX-RS, все параметры запроса будут отображаться в каждом обработчике ресурсов, что приведет к потенциальным конфликтам и путанице.

Если ваш запрос имеет только один «уровень», тогда разница не так уж важна, и два типа параметров эффективно взаимозаменяемы, однако параметры запроса обычно лучше поддерживаются и более широко распознаются. В общем, я бы рекомендовал вам придерживаться параметров запроса для таких вещей, как формы HTML и простые одноуровневые HTTP API.

Тим Сильвестр
источник
2
irrelavant: /?часть представляет ресурс?
Джин Квон
7
?Начинается параметр запроса часть запроса. Параметры запроса являются наиболее распространенным типом параметров URL, в отличие от параметров матрицы. Косая черта перед знаком вопроса гарантирует, что параметр запроса pageне попадает в параметр матрицы, предшествующий косой черте. Я полагаю, что если бы к матрице не были подключены параметры categories, параметры запроса можно было бы http://example.com/res/categories?page=1
добавить
8
Хотя параметры матрицы могут быть указаны в любом сегменте пути, правда, JAX-RS, например, не связывает их с сегментом пути, к которому они были добавлены при введении с помощью @MatrixParam. Согласно "Restful Java с JAX-RS 2.0", запрос типа "GET / mercedes / e55; color = black / 2006 / interior; color = tan" будет иметь неоднозначное определение параметра цветовой матрицы. Хотя, похоже, если вы обрабатываете каждый PathSegment по отдельности, вы можете понять это ... Это очень полезно, но для этого нужно потрудиться, чем если бы вы указали categoryName = foo; objectName = green.
UFL1138
15

В дополнение к ответу Тима Сильвестра я хотел бы привести пример того, как параметры матрицы могут обрабатываться с помощью JAX-RS .

  1. Параметры матрицы в последнем элементе ресурса

    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 с аннотацией пути, в которой вводится значение параметра матрицы.

    ... что подводит нас к пункту 2

  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");
  3. Получить все параметры матрицы как один параметр метода

    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]
Рене Линк
источник
11

- Слишком важно быть отправленным в раздел комментариев .--

Я не уверен, в чём дело с матричными URL. Согласно статье о дизайне w3c, написанной TBL, это была просто идея дизайна, в которой прямо говорится, что она не является особенностью сети. Такие вещи, как относительные URL-адреса, не используются при его использовании. Если вы хотите использовать это, это нормально; просто нет стандартного способа его использования, потому что это не стандарт. - Стив Померой

Итак, короткий ответ: если вам нужен RS для бизнес-целей, вам лучше использовать параметр запроса.

Аджит Ганга
источник
5
Кто-то сказал это разработчикам Angular 2, которые решили, что они настолько уникальны, что им нужно было реализовать это вместо этого!
Мэтт Пиледжи
2
@MattPileggi Я также читаю это из-за Angular 2. Почти каждый аспект Angular 2 является узкоспециализированным, нетрадиционным и противоречит существующим моделям использования. Это пока еще не доказано, что это добавляет смягчающую ценность.
Алуан Хаддад
1
Так что, ребята, я здесь по той же причине, но позвольте мне добавить несколько моментов к этому вопросу с этим вопросом о матрице URL и Google Analytis на странице github 2-й команды angular: github.com/angular/angular/issues/11740 Но после некоторого исследования об этом, нотация матрицы URL кажется более удобочитаемой, чем параметры запроса URL , главным образом, когда нам нужен какой-то параметр в середине или в URL (не только в конце).
Ричард Ли
8
Я думаю, что все, кто считает это нестандартным, тоже не знакомы со спецификацией шаблона uri? Кодирование сложных объектов в параметрах пути является очень полезной функцией шаблонов URI; просто потому, что большинство людей не знают об этом или не используют его, это не означает, что это некий злой заговор угловых разработчиков для внедрения бесполезной сложности в вашу жизнь.
Аякс
2
Пфффт - «<то, чего я не знал, существовало до сих пор>, является нестандартным, таким образом, сохраняя приемлемость моего невежества». То, что TBL сделал или не решил сделать с идеей, в значительной степени несущественно. Это не было особенностью его сети в 2001 году. Функциональные возможности сети - это то, чем их выбирают разработчики клиента и сервера. Если Angular поддерживает матричные параметры, а JAX-RS поддерживает их, и вы выбрали инструменты реализации, тогда продолжайте и используйте то, что работает.
Дейв