Когда я использую параметры params vs. query в API RESTful?
Я хочу сделать свой RESTful API очень предсказуемым. Какова наилучшая практика для принятия решения о сегментировании данных с использованием URI, а не с использованием параметров запроса.
Мне кажется, что системные параметры, которые поддерживают разбиение на страницы, сортировку и группировку, после "?" Но как насчет таких полей, как "статус" и "регион" или другие атрибуты, которые сегментируют вашу коллекцию? Если они также должны быть параметрами запроса, каково главное правило знать, когда использовать параметры пути?
Ответы
Ответ 1
Лучшей практикой для дизайна RESTful API является то, что параметры пути используются для идентификации определенного ресурса или ресурсов, в то время как параметры запроса используются для сортировки/фильтрации этих ресурсов.
Вот пример. Предположим, вы используете конечные точки API RESTful для объекта под названием Car. Вы бы структурировали свои конечные точки следующим образом:
GET /cars
GET /cars/:id
POST /cars
PUT /cars/:id
УДАЛИТЬ /cars/:id
Таким образом, вы используете только параметры пути, когда указываете, какой ресурс будет извлекаться, но это не сортирует/не фильтрует ресурсы каким-либо образом.
Теперь предположим, что вы хотели добавить возможность фильтровать автомобили по цвету в ваших запросах GET. Поскольку цвет не является ресурсом (это свойство ресурса), вы можете добавить параметр запроса, который делает это. Вы должны добавить этот параметр запроса в запрос GET /cars
, например:
GET /cars?color=blue
Эта конечная точка будет реализована так, что будут возвращены только синие автомобили.
Что касается синтаксиса, имена ваших URL должны быть строчными. Если у вас есть имя субъекта, которое, как правило, состоит из двух слов на английском языке, вы должны использовать дефис, чтобы отделить слова, а не дело верблюда.
Ex. /two-words
Ответ 2
Фундаментальный способ думать об этом предмете выглядит следующим образом:
URI - это идентификатор ресурса, который однозначно идентифицирует конкретный экземпляр TYPE ресурса. Как и все остальное в жизни, каждый объект (который является экземпляром какого-либо типа) имеет набор атрибутов, которые являются либо временными, либо временными.
В приведенном выше примере автомобиль - очень осязаемый объект, который имеет такие атрибуты, как make, model и VIN - который никогда не меняется, а цвет, подвеска и т.д. могут со временем меняться. Поэтому, если мы кодируем URI с атрибутами, которые могут меняться со временем (временными), мы можем получить несколько URI для одного и того же объекта:
GET /cars/honda/civic/coupe/{vin}/{color=red}
И спустя годы, если цвет этого самого автомобиля изменится на черный:
GET /cars/honda/civic/coupe/{vin}/{color=black}
Обратите внимание, что сам экземпляр автомобиля (объект) не изменился - это только тот цвет, который изменился. Наличие нескольких URI, указывающих на один и тот же экземпляр объекта, заставит вас создавать несколько обработчиков URI - это не эффективный дизайн и, конечно, не интуитивно понятен.
Следовательно, URI должен состоять только из частей, которые никогда не изменятся и будут по-прежнему однозначно идентифицировать этот ресурс на протяжении всей его жизни. Все, что может измениться, должно быть зарезервировано для параметров запроса, как таковое:
GET /cars/honda/civic/coupe/{vin}?color={black}
Нижняя линия - думаю, полиморфизм.
Ответ 3
В REST API вы не должны чрезмерно беспокоиться о предсказуемых URI. Само предложение предсказуемости URI ссылается на непонимание архитектуры RESTful. Он предполагает, что клиент должен сам создавать URI, чего им действительно не нужно.
Однако я предполагаю, что вы не создаете истинный API REST, а API, основанный на REST (например, на Google Диске). В этих случаях эмпирическим правилом является "путь params = идентификация ресурса" и "параметры запроса = сортировка ресурсов". Итак, возникает вопрос, можете ли вы однозначно идентифицировать свой ресурс БЕЗ статуса/региона? Если да, то, возможно, его параметр запроса. Если нет, то его параметр пути.
НТН.
Ответ 4
Пример URL: /rest/{keyword}
Этот URL является примером параметров пути. Мы можем получить эти данные URL с помощью @PathParam
.
Пример URL: /rest?keyword=java&limit=10
Этот URL является примером параметров запроса. Мы можем получить эти данные URL с помощью @Queryparam
.
Ответ 5
Как только я разработал API, основным ресурсом которого был people
. Обычно пользователи запрашивали отфильтрованный people
, поэтому, чтобы пользователи каждый раз вызывали что-то вроде /people?settlement=urban
, я реализовал /people/urban
, который позже позволил мне легко добавить /people/rural
. Также это позволяет получить доступ к полному списку /people
, если он будет использоваться позже. Короче говоря, мои рассуждения состояли в том, чтобы добавить путь к общим подмножествам
Из здесь:
Псевдонимы для общих запросов
Чтобы сделать API более приятным для среднего потребителя, рассмотрите возможность упаковки наборов условий в легкодоступные пути RESTful. Например, недавно закрытые запросы на билеты могут быть упакованы как GET /tickets/recently_closed
Ответ 6
Вообще говоря, я склонен использовать параметры пути, когда в ресурсе есть очевидная "иерархия", например:
/region/state/42
Если этот единственный ресурс имеет статус, можно:
/region/state/42/status
Однако, если "область" на самом деле не является частью раскрываемого ресурса, она, вероятно, относится к одному из параметров запроса - похожа на разбиение на страницы (как вы упомянули).
Ответ 7
Сегментация более иерархична и "хороша", но может быть ограничена.
Например, если у вас есть URL с тремя сегментами, каждый из которых передает разные параметры для поиска автомобиля по марке, модели и цвету:
www.example.com/search/honda/civic/blue
Это очень красивый URL-адрес и более легко запоминается конечным пользователем, но теперь ваш вид застрял в этой структуре. Скажите, вы хотите сделать так, чтобы в поиске пользователь мог искать ВСЕ синие автомобили или ВСЕ Honda Civics? Параметр запроса решает это, потому что он дает пару ключевых значений. Итак, вы можете передать:
www.example.com/search?color=blue
www.example.com/search?make=civic
Теперь у вас есть способ ссылаться на значение через его ключ - либо "цвет", либо "сделать" в вашем запросе.
Вы можете обойти это, возможно, используя больше сегментов, чтобы создать своего рода структуру ключевых значений, например:
www.example.com/search/make/honda/model/civic/color/blue
Надеюсь, что это имеет смысл.