REST, возвращающий граф объекта - PullRequest
9 голосов
/ 23 декабря 2008

Я новичок в REST architecural design, однако я думаю, что у меня есть основы этого.

У меня проблема с возвратом объектов из вызова RESTful. Если я сделаю запрос, такой как http://localhost/{type A} / {id}, я верну экземпляр A из базы данных с указанным идентификатором.

Мой вопрос: что происходит, когда A содержит коллекцию объектов B? В настоящий момент генерируемый мной XML возвращает A с набором объектов B внутри него. Как вы можете себе представить, если тип B имеет коллекцию объектов C, тогда возвращаемый XML будет довольно сложным графом объектов.

Я не могу быть уверен на 100%, но это противоречит принципам RESTful, XML для A должен возвращать поля и т. Д. Для A, а также набор URI в коллекцию B, которой он владеет.

Извините, если это немного сбивает с толку, я могу попытаться уточнить подробнее. Это кажется относительно основным вопросом, однако я не могу решить, какой подход является «более» RESTful.

Приветствия

Айдос

Ответы [ 3 ]

9 голосов
/ 23 декабря 2008

Один из важнейших принципов RESTful заключается в том, что у всего есть URI.

У вас есть такой URI.

  • / A / и / A / id / для получения списка A и конкретного A. Ответ A включает идентификаторы B.
  • / B / и / B / id /, чтобы получить список B и конкретного B. Ответ B включает идентификаторы C.
  • / C / и / C / id /, чтобы получить список C и конкретного C.

Через серию запросов вы можете перестроить структуру A-B-C. Вы получаете A, затем получаете соответствующие B. Получая B, вы получаете различные C, на которые ссылаются.


Редактировать

Ничто не мешает вам больше возвращаться.

Например, у вас могут быть следующие типы URI.

  • /flat/A/id/, /flat/B/id/ и /flat/C/id/ для возврата "плоских" (т.е. без глубины) структур.

  • /deep/A/id/, /deep/B/id/ и /deep/C/id/ для возврата структур с полной глубиной.

/deep/A/id/ будет всей структурой в большом вложенном XML-документе. Хорошо для клиентов, которые могут справиться с этим. /flat/A/id/ будет просто верхним уровнем в плоском документе. Лучше всего для клиентов, которые не могут справиться с глубиной.

5 голосов
/ 23 декабря 2008

Ничто не говорит о том, что ваш интерфейс REST не может быть реляционным.

  1. / книжный магазин / {bookstoreID}
  2. / книжный / {bookstoreID} / книги
  3. / книга / {BookID}

По сути, у вас есть соответствие 1: 1 вашей схеме БД.

За исключением отношений «многие ко многим», образующих дочерние списки. Например, / bookstore / 657 / books должен возвращать список идентификаторов книг или URL-адресов. Затем, если вам нужны данные конкретной книги, вы можете использовать третий URL.

Это просто не в моей голове, пожалуйста, обсудите достоинства.

0 голосов
/ 23 декабря 2008

Создайте плоскую вселенную, которую вы выставляете миру.

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

Ваша объектная вселенная внутри вашего приложения не обязательно является той же, которую вы представляете миру. Пусть у A есть дочерние элементы, а у B - дочерние, но нет необходимости отражать это в URL-адресах запросов REST.

Зачем расплющивать? Потому что тогда вы можете делать такие вещи, как выборка объектов позже по идентификатору, или отправлять их пакетами (в одном и том же случае, более или менее) ... И, что лучше всего, URI запроса не изменяются при изменении иерархии объектов (объект 37252 всегда один и тот же, даже если он был переклассифицирован).

Редактировать: Ну, вы просили об этом ... Вот архитектура, которую я использовал в конечном итоге: package: server - содержит суперклассы, которые совместно используются внешним сервером и внутренним сервером

package: frontEndServer - содержит интерфейс сервера, которого должен придерживаться интерфейсный сервер. Интерфейс хорош, потому что если вы решите перейти с SOAP на прямой веб-клиент (который также использует JSON или что-то еще), вы получите интерфейс полностью продуманным. Он также содержит все реализации для классов frontEnd, которые будут брошены клиенту, и всю логику взаимодействия между классами, за исключением того, как разговаривать с клиентом .

package: backEndServer - содержит интерфейс сервера, которого будет придерживаться внутренний сервер. Примером реализации Сервера может быть тот, который общается с БД MySql или тот, который общается с БД XML, но интерфейс Сервера нейтрален. Этот пакет также содержит все классы, которые реализации интерфейса сервера используют для выполнения работы, и всю логику для бэкэнда, кроме персистентности.

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

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

...