обзор
Архитектурный шаблон REST основан на двух основных принципах:
- Ресурсы в виде URL: ресурс — это что-то вроде сущности или существительного в моделировании языка. Все в сети идентифицируется как ресурс, и каждый уникальный ресурс идентифицируется уникальным URL.
- Операции как методы HTTP: REST использует существующие методы HTTP, в частности, GET, PUT, POST и DELETE, которые соответствуют операциям чтения, создания, изменения и удаления ресурса соответственно.
Любое действие, выполняемое клиентом по HTTP, содержит URL и метод HTTP. URL представляет ресурс, а метод HTTP представляет действие, которое необходимо выполнить над ресурсом.
Будучи широким архитектурным стилем, REST всегда имеют разные интерпретации. Неоднозначность усугубляется тем фактом, что HTTP-методов недостаточно для поддержки обычных операций. Одним из наиболее распространенных примеров является отсутствие метода « поиска ». Поиск является одной из наиболее широко используемых функций в различных приложениях, но не было стандартов для реализации этой функции. Из-за этого разные люди склонны проектировать поиск по-разному. Учитывая, что REST направлен на унификацию сервисной архитектуры, любая неоднозначность должна рассматриваться как ослабление аргумента для REST.
Далее в этом документе мы обсудим, как можно упростить поиск по REST. Мы не стремимся к разработке стандартов для поиска RESTful, но мы будем обсуждать, как можно решить эту проблему.
Требования к поиску
Функция поиска, которая в основном используется в разных веб-приложениях, поддерживает практически одинаковые функции в разных приложениях. Ниже приведен список некоторых общих компонентов функций поиска:
- Поиск по одному или нескольким критериям одновременно
- Поиск автомобилей красного цвета типа хэтчбек
- цвет = красный && тип = хэтчбек
- Реляционная и условная поддержка оператора
- Поиск красного или черного автомобиля с пробегом больше 10
- Цвет = красный | черный && пробег> 10
- Подстановочный поиск
- Поиск автомобиля, произведенного от названия компании, начинающейся с M
- Компания = M *
- пагинация
- Перечислите все автомобили, но получите 100 результатов одновременно
- upperLimit = 200 && lowerLimit = 101
- Диапазон поиска
- Принеси мне все машины, выпущенные в период с 2000 по 2010 год
- год запуска между (2000, 2010)
Когда мы поддерживаем поиск с такими функциями, сам дизайн интерфейса поиска становится сложным. И при реализации в среде REST выполнить все эти требования (при этом все еще в соответствии с REST!) Сложно.
Возвращаясь к основным принципам REST, теперь у нас остались два вопроса:
- Какой метод HTTP использовать для «поиска» ?
- Как создать эффективный ресурс URL для поиска?
- Параметры запроса и встроенные URL
- Критерии фильтра моделирования
Выбор метода HTTP
Критерии запроса и встроенные критерии. По сути, REST классифицирует операции по своей природе и связывает четко определенную семантику с этими категориями. Идемпотентными операциями являются GET, PUT и DELETE (GET только для чтения, PUT для обновления, DELETE для удаления). Метод POST используется для неидемпотентных процедур, таких как create.
По определению, поиск — это операция только для чтения, которая используется для запроса коллекции ресурсов, отфильтрованных по некоторым критериям. Таким образом, метод GET HTTP для функции поиска является очевидным выбором. Однако в GET мы ограничены размером URL, если добавляем сложные критерии в URL.
Представление URL
Давайте обсудим это на примере: пользователь хочет искать четырехдверный седан синего цвета; как должен выглядеть URL ресурса для этого запроса? Ниже два разных URL синтаксически разные, но семантически одинаковые:
- / автомобили /? цвет = синий и тип = седан & двери = 4
- / Автомобили / Цвет: синий / тип: седан / двери: 4
Оба приведенных выше URL соответствуют RESTful-способу представления запроса ресурса, но представлены по-разному. Первый использует критерии запроса URL, чтобы добавить детали фильтрации, в то время как второй использует подход встроенного URL.
Подход со встроенным URL-адресом более удобен для чтения и может использовать преимущества собственных механизмов кэширования, которые существуют на веб-сервере для трафика HTTP. Но этот подход ограничивает пользователя, чтобы предоставить параметр в определенном порядке. Неправильные положения параметров приведут к ошибке или нежелательному поведению. Ниже два выглядит одинаково, но может не дать вам правильных результатов
- / авто / цвет: красный / тип: седан
- / Автомобили / Тип: седан / цвет: красный
Кроме того, поскольку не существует стандартизации для критериев встраивания, люди могут стремиться использовать свой собственный способ представления.
Итак, мы рассматриваем подход критериев запроса поверх подхода встроенного URL, хотя представление является немного сложным и не имеет удобочитаемости
Критерии фильтра моделирования: страница результатов поиска по сути является RESTful, хотя ее URL-адрес идентифицирует запрос. URL должен включать элементы, подобные SQL. Хотя SQL предназначен для фильтрации данных, извлекаемых из реляционных данных, новый язык моделирования должен иметь возможность фильтровать данные из иерархического набора ресурсов. Этот язык должен помочь в разработке механизма передачи сложных поисковых запросов по URL-адресам. В этом разделе далее два таких стиля обсуждаются подробно.
- Язык запроса элемента канала (FIQL). Язык запроса элемента канала (FIQL, произносится как «переменчивый») — это простой, но гибкий, дружественный к URI синтаксис для выражения фильтров между записями в синдицированном канале. Эти выражения фильтра могут отображаться в любой службе RESTful и могут помочь в моделировании сложных фильтров. Ниже приведены некоторые примеры таких веб-URL для соответствующих им SQL.
SQL
|
REST Search URLs
|
выберите * из актеров, где firstname = ‘PENELOPE’ и фамилия = ‘GUINESS’ | / актеры _s = Firstname == PENELOPE;? Lastname == Guiness |
выберите * из актеров, где фамилия, как ‘PEN%’ | / Актеры? _S = == Lastname PEN * |
выберите * из фильмов, где filmid = 1 и Rentalduration <> 0 | / Фильмы _s = FilmID == 1;? Rentalduration = 0! |
выберите * из фильмов, где filmid> = 995 | / Фильмы _s = FilmID = GE = 995 |
выберите * из фильмов, где дата выхода <’27/05/2005′ | /film?_s=releasedate=le=2005-05-27T00:00:00.000%2B00:00 |
- Resource Query Language (RQL) : Resource Query Languages (RQL) определяет синтаксически простой язык запросов для запросов и получения ресурсов. RQL разработан для удобства использования URI, особенно в качестве компонента запроса URI, и обладает высокой расширяемостью. RQL — это расширенный набор HTML-кодировок URL-адресов для значений форм и расширенный набор языка запросов элементов фида (FIQL). RQL в основном состоит из набора вложенных именованных операторов, каждый из которых имеет набор аргументов и оперирует набором ресурсов.
Casestudy: функции расширенного поиска Apache CXF
Для поддержки возможностей расширенного поиска Apache CXF внедрил поддержку FIQL в своей реализации JAX-RS с выпуска 2.3.0. С помощью этой функции пользователи теперь могут выражать сложные поисковые выражения, используя URI. Ниже приведено подробное примечание о том, как использовать эту функцию:
Для работы с запросами FIQL необходимо ввести SearchContext в код приложения и использовать его для получения SearchCondition, представляющего текущий запрос FIQL. Это условие поиска может быть использовано несколькими способами для поиска подходящих данных.
01
02
03
04
05
06
07
08
09
10
11
12
|
@Path ( "books" ) public class Books { private Map books; @Context private SearchContext context; @GET public List getBook() {SearchCondition sc = searchContext.getCondition(Book. class ); //SearchCondition is method can also be used to build a list of// matching beans iterate over all the values in the books map and // return a collection of matching beans List found = sc.findAll(books.values()); return found; } } |
SearchCondition также можно использовать для получения доступа ко всем поисковым требованиям (изначально выраженным в FIQL) и для ручного сравнения с локальными данными. Например, SearchCondition предоставляет служебный метод toSQL (String tableName, String… columnNames), который внутренне анализирует все поисковые выражения, составляющие текущий запрос, и преобразует их в выражение SQL:
01
02
03
04
05
06
07
08
09
10
|
// find all conditions with names starting from 'ami' // and levels greater than 10 : // ?_s="name==ami*;level=gt=10" SearchCondition sc = searchContext.getCondition(Book. class ); assertEquals("SELECT * FROM table WHERE name LIKE 'ami%' AND level > '10' ", sq.toSQL( "table" )); |
Вывод
Запрос данных является критическим компонентом большинства приложений. С появлением богатых клиентских приложений Ajax и баз данных, ориентированных на документы, необходимы новые методы запросов; эти методы должны быть простыми, но расширяемыми, предназначенными для работы внутри URI и запроса коллекций ресурсов. Движение NoSQL открывает путь к более модульному подходу к базам данных и отделяет моделирование, валидацию и запросы запросов от проблем хранения, но нам нужны новые подходы запросов, чтобы соответствовать более современному архитектурному дизайну.
Ссылка: класс струн Гуавы от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events .