Лучшая практика REST для получения списка подмножеств

Я прочитал статью в REST - сложных приложениях и отвечает на некоторые из моих вопросов, но не все.

Я разрабатываю свое первое приложение REST и должен возвращать списки подмножества в запросы GET. Что из следующего более "RESTful"?

/patients;listType=appointments;date=2010-02-22;user_id=1234

или

/patients/appointments-list;date=2010-02-22;user_id=1234

или даже

/appointments/2010-02-22/patients;user_id=1234

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

/patients;rounds=true;specific_id=xxxx;covering_id=yyyy;primary_id=zzzz

но для получения правильного списка потребуется сложная ветвящаяся логика, где запрос на конкретное подмножество (rounds-list) достигнет того же самого.

Обратите внимание, что мне нужно использовать параметры матрицы вместо параметров запроса, потому что мне нужно выполнить фильтрацию на нескольких уровнях URL. Рамка, которую я использую (RestEasy), полностью поддерживает параметры матрицы.

Ответ 1

Ральф,

конкретные шаблоны URI ортогональны вопросу о том, как RESTful будет вашим приложением.

В отношении RESTfulness важно, чтобы клиент обнаружил, как создавать URI во время выполнения. Это может быть достигнуто либо с помощью форм, либо с помощью шаблонов URI. Оба элемента управления гипермедиа сообщают клиенту, какие параметры могут быть использованы, и где их помещать в URI.

Чтобы это работало RESTfully, клиент и сервер должны знать возможные параметры во время разработки. Обычно это достигается путем включения их в спецификацию отношения ссылки.

Вы можете, например, определить отношение ссылки "my-subset", чтобы иметь смысл связывания с подмножествами коллекций, и с ним вы бы определили следующие параметры:

listType, date, userID.

В шаблоне ссылки эта спецификация может использоваться как

< link rel= "my-subset" template = "/{listType}/{date}/patient; user_id = {userID}" / >

Обратите внимание на то, как имя фактического параметра в URI отделено от указанного имени параметра. Значение для userID ограничено параметром user_id URI.

Это позволяет изменять имя параметра URI, не затрагивая клиента.

Вы можете посмотреть документы описания OpenSearch (http://www.opensearch.org), чтобы увидеть, как это делается на практике.

На самом деле, вы должны иметь возможность использовать OpenSearch совсем немного для вашего варианта использования. В частности, возможность предопределять запросы позволит вам описать определенные подмножества в ваших "формах".

Но посмотрите сами, а затем снова спросите: -)

Jan

Ответ 2

Я бы рекомендовал использовать эту структуру URL:

/appointments;user_id=1234;date=2010-02-22

Почему? Я выбрал /appointments, потому что это просто и понятно. (Если у вас более одного вида встречи, дайте мне знать в комментариях, и я могу настроить свой ответ.) Я выбрал точки с запятой, потому что они не подразумевают иерархию между user_id и датой.

Еще одна вещь: нет причин, по которым вы должны ограничиться одним URL. Очень просто иметь несколько структур URL, которые ссылаются на один и тот же ресурс. Поэтому вы также можете использовать:

/users/1234/appointments;date=2010-02-22

Чтобы вернуть аналогичный результат.

Тем не менее, я бы не рекомендовал использовать /dates/2010-02-22/appointments;user_id=1234. Зачем? На практике я не думаю, что /dates относится к ресурсу. Дата является атрибутом назначения, но сама по себе не является существительным (т.е. Это не первоклассная вещь).

Ответ 3

Я могу рассказать о том, что ответил Давид Джеймс.
Формат ваших URI может быть таким, как он предложил:

/appointments;user_id=1234;date=2010-02-22

и/или

/users/1234/appointments;date=2010-02-22

сохраняя при этом доступность (во время выполнения) ваших URI ресурсов (как предложил Ян Альгермиссен).