Когда использовать @QueryParam vs @PathParam

Я не задаю вопрос, который уже задан здесь: В чем разница между @PathParam и @QueryParam

Это вопрос "наилучшей практики" или конвенции.

Когда вы используете @PathParam vs @QueryParam.

Что я могу думать о том, что решение могло бы использовать эти два, чтобы различать шаблон информации. Позвольте мне проиллюстрировать ниже мой LTPO - менее совершенное наблюдение.

Использование PathParam может быть зарезервировано для категории информации, которая прекрасно впишется в ветвь информационного дерева. PathParam можно использовать для перехода к иерархии классов объектов.

В то время как QueryParam может быть зарезервирован для указания атрибутов для поиска экземпляра класса.

Например,

  • /Vehicle/Car?registration=123
  • /House/Colonial?region=newengland

/category?instance

@GET
@Path("/employee/{dept}")
Patient getEmployee(@PathParam("dept")Long dept, @QueryParam("id")Long id) ;

vs /category/instance

@GET
@Path("/employee/{dept}/{id}")
Patient getEmployee(@PathParam("dept")Long dept, @PathParam("id")Long id) ;

vs ?category+instance

@GET
@Path("/employee")
Patient getEmployee(@QueryParam("dept")Long dept, @QueryParam("id")Long id) ;

Я не думаю, что это стандартная конвенция. Здесь? Однако я хотел бы услышать, как люди используют PathParam vs QueryParam для дифференциации их информации, как я показал выше. Я также хотел бы услышать причину этой практики.

Ответ 1

REST не может быть стандартом как таковой, но чтение общей документации REST и сообщений в блоге должно дать вам некоторые рекомендации по эффективному структурированию URL-адресов API. Большинство API-интерфейсов для отдыха имеют только имена ресурсов и идентификаторы ресурсов в пути. Такие как:

/departments/{dept}/employees/{id}

Некоторые API-интерфейсы REST используют строки запросов для фильтрации, разбивки на страницы и сортировки, но поскольку REST не является строгим стандартом, я бы рекомендовал проверять некоторые API REST, такие как github и stackoverflow, и посмотреть, что может хорошо работать для вашего использования.

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

Ответ 2

Это то, что я делаю.

Если есть сценарий для получения записи на основе идентификатора, например, вам нужно получить сведения о сотруднике с идентификатором 15, тогда вы можете иметь ресурс с @PathParam.

GET /employee/{id}

Если есть сценарий, когда вам нужно получить информацию о всех сотрудниках, но только 10 за раз, вы можете использовать параметр запроса

GET /employee?start=1&size=10

Это говорит о том, что начиная идентификатор сотрудника 1 получает десять записей.

Подводя итог, используйте @PathParam для извлечения на основе id. Пользователь @QueryParam для фильтра или если у вас есть фиксированный список опций, которые пользователь может передать.

Ответ 3

Я думаю, что если параметр идентифицирует конкретный объект, вы должны использовать переменную пути. Например, чтобы получить все сообщения в моем блоге, я прошу

GET: myserver.com/myblog/posts

чтобы получить сообщение с id = 123, я бы запросил

GET: myserver.com/myblog/posts/123

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

GET: myserver.com/myblog/posts?since=2013-01-01

В первом примере "сообщения" идентифицирует конкретный объект (весь сбор сообщений в блоге). Во втором примере "123" также представляет собой конкретную сущность (одно сообщение в блоге). Но в последнем примере параметр "since = 2013-01-01" - это запрос на фильтрацию коллекций сообщений, а не отдельного объекта. Еще одним хорошим примером может служить разбивка на страницы и упорядочение, т.е.

GET: myserver.com/myblog/posts?page=2&order=backward

Надеюсь, что это поможет.: -)

Ответ 4

Вы можете использовать параметры запроса для фильтрации и параметры пути для группировки. Следующая ссылка имеет хорошую информацию об этом Когда использовать pathParams или QueryParams

Ответ 5

Я лично использовал подход "если имеет смысл для пользователя закладок URL, который включает эти параметры, то используйте PathParam".

Например, если URL-адрес профиля пользователя включает в себя некоторый параметр идентификатора профиля, поскольку он может быть помещен в закладки пользователем и/или отправлен по электронной почте, я бы включил этот идентификатор профиля в качестве параметра пути. Кроме того, еще одно обстоятельство заключается в том, что страница, обозначенная URL-адресом, которая включает параметр пути, не изменяется - пользователь настроит свой профиль, сохранит его, а затем вряд ли сильно изменит его; это означает, что веб-браузеры/поисковые системы/браузеры/etc могут кэшировать эту страницу на основе пути.

Если параметр, переданный в URL-адресе, скорее всего, изменит макет страницы/контент, я бы использовал его как queryparam. Например, если URL-адрес профиля поддерживает параметр, который указывает, показывать ли пользователю электронную почту или нет, я считаю, что это параметр запроса. (Я знаю, возможно, вы могли бы сказать, что &noemail=1 или любой другой параметр, который он может использовать в качестве параметра пути, и генерирует две отдельные страницы: одну с электронной почтой на ней, без нее, но логически, что не case: это та же самая страница с определенными атрибутами или без них.

Надеюсь, что это поможет - я понимаю, что объяснение может быть немного нечетким:)

Ответ 6

Это очень интересный вопрос.

Вы можете использовать оба из них, там нет строгого правила по этому вопросу, но использование переменных пути URI имеет некоторые преимущества:

  • Cache: Большинство служб веб-кэша в Интернете не кэшируют запрос GET, когда они содержат параметры запроса. Они делают это, потому что существует множество RPC-систем, использующих запросы GET для изменения данных на сервере (сбой!! Get должен быть безопасным методом)

Но если вы используете переменные пути, все эти службы могут кэшировать ваши запросы GET.

  • Иерархия: Переменные пути могут представлять иерархию: /Город/Улица/место

Он предоставляет пользователю дополнительную информацию о структуре данных.

Но если ваши данные не имеют отношения к иерархии, вы все равно можете использовать переменные Path, используя запятую или запятую:

/Город/долгота, широта

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

/IconGenerator/красный, синий, зеленый

Помимо этих причин, есть некоторые случаи, когда очень часто используются переменные строки запроса:

  • Когда вам нужно, чтобы браузер автоматически помещал переменные формы HTML в URI
  • Когда вы имеете дело с алгоритмом. Например, движок google использует строки запроса:

http://www.google.com/search?q=rest

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

Ответ 7

Как уже отмечалось, REST не является стандартом. Однако, если вы хотите внедрить соглашение об URI на основе стандартов, вы можете рассмотреть oData соглашение URI. Ver 4 был одобрен как стандарт OASIS и существуют библиотеки для oData для разных языков, включая Java, через Apache Olingo. Не позволяйте факту, что он появился из Microsoft, отложил вас, так как получил поддержку от других игроков отрасли, в том числе Red Hat, Citrix, IBM, Blackberry, Drupal, Netflix Facebook и SAP

Ниже перечислены дополнительные пользователи

Ответ 8

Причина на самом деле очень проста. При использовании параметра запроса вы можете взять символы, такие как "/", и вашему клиенту не нужно кодировать HTML-код. Есть и другие причины, но это простой пример. Что касается использования переменной пути. Я бы сказал, всякий раз, когда вы имеете дело с идентификаторами или если переменная пути является направлением для запроса.

Ответ 9

  • @QueryParam можно удобно использовать с аннотацией по умолчанию, чтобы исключить исключение нулевого указателя, если не передан параметр запроса.

Если вы хотите анализировать параметры запроса из запроса GET, вы можете просто определить соответствующий параметр для метода, который будет обрабатывать запрос GET и аннотировать их с помощью аннотации @QueryParam

  1. @PathParam извлекает значения URI и соответствует @Path. И, следовательно, получает входной параметр. 2.1 @PathParam может быть более одного и установлен в аргументы методов

    @Path ( "/отдых" )

    открытый класс Abc {

    @GET

    @Path ( "/тзд/{р0}/{р1}" )

    @Produces ( "текст/обычный" )

    public String add (@PathParam ( "p0" ) Целое число param1, @PathParam ( "p1" ) Целое число param2) {

     return String.valueOf(param1+param2);
    

    } }

В приведенном выше примере

http://localhost:8080/Restr/rest/msg/ {p0}/{p1},

p0 соответствует param1 и p1 соответствует param2. Итак, для URI

http://localhost:8080/Restr/rest/msg/4/6,

получаем результат 10.

В службе REST JAX-RS предоставляет @QueryParam и @FormParam как для приема данных из HTTP-запроса. Форма HTTP может быть представлена ​​различными методами, такими как GET и POST.

@QueryParam: принимает запрос GET и считывает данные из строки запроса.

@FormParam: принимает запрос POST и извлекает данные из формы HTML или любого запроса носителя

Ответ 10

Из Википедии: Единый указатель ресурса

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

Необязательный запрос, отделенный от предыдущей части вопросительным знаком (?), содержащий строку запроса неиерархических данных.

- В соответствии с концептуальным дизайном URL-адреса мы можем реализовать PathParam для иерархических компонентов данных/директив/локаторов или реализовать QueryParam, когда данные не являются иерархическими. Это имеет смысл, потому что пути естественно упорядочены, тогда как запросы содержат переменные, которые могут быть упорядочены произвольно (неупорядоченные пары переменных/значений).

Предыдущий комментатор написал:

Я думаю, что если параметр идентифицирует конкретный объект, вы должны использовать переменную пути.

Другой написал:

Использовать @PathParam для поиска на основе идентификатора. Пользователь @QueryParam для фильтра или если у вас есть фиксированный список опций, которые пользователь может передать.

Другой

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

- Однако можно реализовать гибкую, неиерархическую систему для идентификации конкретных объектов! В таблице SQL можно указать несколько уникальных индексов и позволить идентифицировать объекты с помощью любой комбинации полей, которые содержат уникальный индекс! Различные комбинации (возможно, также упорядоченные по-разному) могут использоваться для ссылок из разных связанных объектов (рефереров). В этом случае мы можем иметь дело с неиерархическими данными, которые используются для идентификации отдельных объектов - или в других случаях могут указывать только определенные переменные/поля - определенные компоненты уникальных индексов - и извлекать список/набор записей. В таких случаях было бы проще, логичнее и разумнее реализовать URL-адреса как QueryParams!

Может ли длинная шестнадцатеричная строка разбавлять/уменьшать значение ключевых слов в остальной части пути? Возможно, стоит подумать о потенциальных последствиях SEO для размещения переменных/значений в пути или в запросе и о последствиях для человеческого интерфейса, хотим ли мы, чтобы пользователи были способный отслеживать/исследовать иерархию URL-адресов, редактируя содержимое адресной строки. На моей странице 404 Not Found используются переменные SSI для автоматической перенаправления сломанных URL-адресов их родителям! Поисковые роботы также могут пересекать иерархию путей. С другой стороны, лично, когда я обмениваюсь URL-адресами в социальных сетях, я вручную выделяю любые частные уникальные идентификаторы - обычно путем усечения запроса из URL-адреса, оставляя только путь: в этом случае есть некоторая полезность при размещении уникальных идентификаторов в пути, а не в запросе. Хотим ли мы облегчить использование компонентов пути в качестве грубого пользовательского интерфейса, возможно, это зависит от того, являются ли данные/компоненты доступными для человека или нет. Вопрос о удобочитаемости человека в некоторой степени относится к вопросу об иерархии: часто данные, которые могут быть выражены как человекочитаемые ключевые слова, также являются иерархическими; в то время как иерархические данные часто могут быть выражены как человекочитаемые ключевые слова. (Сами поисковые системы могут быть определены как увеличение использования URL-адресов в качестве пользовательского интерфейса.) Иерархии ключевых слов или директив могут не строго упорядочиваться, но они обычно достаточно близки, чтобы мы могли охватывать альтернативные случаи в пути, а отметьте один вариант как "канонический" случай.

Существует принципиально несколько вопросов, на которые мы можем ответить с URL-адресом для каждого запроса:

  • Какую запись/вещь мы запрашиваем/обслуживаем?
  • Какое (-ы) нас интересует?
  • Как мы хотим представить информацию/записи?

Q1 почти наверняка лучше всего покрывается контуром или PathParams. Q3 (который, вероятно, управляется с помощью набора произвольно упорядоченных необязательных параметров и значений по умолчанию); почти наверняка лучше всего покрывается QueryParams. Q2: Это зависит...

Ответ 11

Вы можете поддерживать как параметры запроса, так и параметры пути, например, в случае агрегирования ресурсов - когда сбор суб-ресурсов имеет смысл сам по себе.

/departments/{id}/employees
/employees?dept=id

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

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

/inventory?make=toyota&model=corolla
/inventory?year=2014

Использовать параметры запроса для объединения ортогональных иерархий.

/inventory/makes/toyota/models/corolla?year=2014
/inventory/years/2014?make=toyota&model=corolla
/inventory?make=toyota&model=corolla&year=2014

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

/words/{id}/definitions
/definitions?word=id   // not useful

Ответ 12

Я даю одно выражение для undersand, когда мы используем @Queryparam и @pathparam

Например, я беру один resouce carResource class

Если вы хотите сделать входные данные вашего метода resouce manadatory, используйте тип параметра как @pathaparam, если входы вашего ресурсного метода должны быть необязательными, сохраните этот тип параметра как @Queryparam param

@Path("/car")
class CarResource
{
    @Get
    @produces("text/plain")
    @Path("/search/{carmodel}")
    public String getCarSearch(@PathParam("carmodel")String model,@QueryParam("carcolor")String color) {
        //logic for getting cars based on carmodel and color
            -----
        return cars
    }
}

Для этого resouce передать запрос

req uri ://address:2020/carWeb/car/search/swift?carcolor=red

Если вы дадите req, как это, resouce даст модель автомобиля и цвет

 req uri://address:2020/carWeb/car/search/swift

Если вы дадите req, как это, метод resoce отобразит только модель с быстрой моделью

req://address:2020/carWeb/car/search?carcolor=red

Если вы так дадите, мы получим исключение ResourceNotFound, потому что в классе car resouce я объявил carmodel как @pathPram, то есть вы должны и должны дать carmodel как reQ uri, иначе он не будет передавать req, чтобы возобновить, но если вы не пропускайте цвет, и он передаст req ресурсу, потому что цвет @quetyParam он необязателен в req.

Ответ 13

В двух словах,

@Pathparam работает для передачи значения через ресурсы и строку запроса

  • /Пользователь/1
  • /Пользователь? ID = 1

@Queryparam работает только для передачи значений Query String

  • /Пользователь? ID = 1