Параметри матриці URL проти параметрів запиту


176

Мені цікаво, чи використовувати параметри матриці чи запиту у своїх URL-адресах. Я вважав, що старі дискусії на цю тему не задовольняють.

Приклади

На перший погляд матричні парами, здається, мають лише переваги:

  • більш читабельний
  • не потрібно кодувати та розшифровувати "&" в XML-документах
  • URL-адреси з "?" не є кешованим у багатьох випадках; URL-адреси з параметри матриці кешуються
  • Параметри матриці можуть з'являтися скрізь на шляху і не обмежуються її кінцем
  • Параметри матриці можуть мати більше одного значення: paramA=val1,val2

Але є і недоліки:

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

Оскільки розробник служби може вибрати рамку з підтримкою параметри матриці, єдиним недоліком буде те, що браузери створюють за замовчуванням параметри запиту.

Чи є інші недоліки? Що б ти зробив?


10
Я не впевнений, яка велика справа в матричних URL-адресах. Відповідно до статті дизайну w3c, яку написав TBL, це була лише ідея дизайну і прямо заявляє, що це не особливість Інтернету. Такі речі, як відносні URL-адреси, не використовуються при його використанні. Якщо ви хочете використовувати його, це добре; просто немає стандартного способу його використання, оскільки це не стандарт.
Стів Померой

2
@Steve Pomeroy: Це стаття, яку ви згадуєте: w3.org/DesignIssues/MatrixURIs.html
Marcel

3
@Marcel: так. Для тих, хто думає про матричні URL-адреси, зверніть увагу на "Стан: особистий погляд" у верхній частині документа.
Стів Померой

чи можуть параметри матриці мати більше одного значення? справді?
Айяш

Відповіді:


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 форми та прості однорівневі API HTTP.


2
ірлавант: чи є /?частина, що представляє ресурс?
Джин Квон

7
?Починається параметр запиту частина запиту. Параметри запиту - це найпоширеніший тип параметрів URL, на відміну від матричних параметрів. Похила перед знаком питання переконує, що параметр запиту pageне впадає в параметр матриці, який передує косою рисою. Я думаю, якби не було додано жодних матричних параметрів categories, параметри запиту могли бути прикріплені без косої лінії так:http://example.com/res/categories?page=1
Teemu Leisti

8
Хоча це правда, що параметри матриці можуть бути вказані в будь-якому сегменті шляху, наприклад, JAX-RS не пов'язує їх із сегментом шляху, до якого вони були додані під час ін'єкції з @MatrixParam. Відповідно до "Затишної Java з JAX-RS 2.0", запит типу "GET / mercedes / e55; color = black / 2006 / interior; color = tan" мав би неоднозначне визначення параметри кольорової матриці. Хоча це виглядає так, що якщо ви обробляєте кожен PathSegment окремо, ви можете розібратися в цьому… Настільки корисно, але більше роботи, щоб дістатися до нього, ніж якщо ви вказали категоріюName = 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]

    Оскільки параметри матриці надаються як a, 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]

10

- Важливо відпустити коментар до розділу .--

Я не впевнений, яка велика справа в матричних URL-адресах. Відповідно до статті дизайну w3c, яку написав TBL, це була лише ідея дизайну і прямо заявляє, що це не особливість Інтернету. Такі речі, як відносні URL-адреси, не використовуються при його використанні. Якщо ви хочете використовувати його, це добре; просто немає стандартного способу його використання, оскільки це не стандарт. - Стів Померой

Отже, коротка відповідь - якщо вам потрібна RS для ділових цілей, вам краще скористатися параметром запиту.


5
Хтось розповідає, що розробникам Angular 2, які вирішили, що вони настільки унікальні, потрібно замість цього здійснити!
Метт Пілегі

2
@MattPileggi Я також читаю це через кут 2. Практично кожен аспект Angular 2 є вузькоспеціалізованим, нетрадиційним та суперечить існуючим моделям використання. Наразі це ще не доведено, що це додає пом'якшувальної цінності.
Алуан Хаддад

1
Отже, хлопці, я тут теж з тієї ж причини, але дозвольте мені додати деякі моменти до цього дискусії з цим питанням про матрицю url та google analytis на кутовій сторінці github 2 команди: github.com/angular/angular/isissue/11740 Але після деяких досліджень про це, позначення матриці URL виглядає більш зрозумілим для людини, ніж параметри запиту URL , головним чином, коли нам потрібен якийсь параметр посередині або URL (не лише в кінці його).
Річард Лі

8
Я думаю, кожен, хто вважає це нестандартним, теж не знайомий зі специфікацією шаблону Uri? Кодування складних об'єктів у парамах шляху - дуже корисна особливість шаблонів урі; тільки тому, що більшість людей не знає про це і не використовує це не означає, що це якась зла змова кутовими дисками, щоб ввести у ваше життя марну складність.
Аякс

2
Pffft - "<те, про що я досі не знав, існувало> є нестандартним, таким чином зберігаючи прийнятність мого невігластва". Те, що TBL зробив чи не вирішив зробити з цією ідеєю, в основному не має значення. Це не було особливістю його Інтернету у 2001 році. Особливості Інтернету є такими, якими вони обирають клієнт та серверні виконавці. Якщо Angular підтримує параметри матриці, а JAX-RS підтримує їх, і це вибрані вами інструменти реалізації, тоді продовжуйте та використовуйте те, що працює.
Дейв
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.