2016-11-06 6 views
7

Предположим, я хочу создать интерфейс RESTful, и я хочу работать с foo s на основе их идентификаторов. Ничего нового здесь:Рекомендации по возврату представления ресурса, который также является коллекцией

  • GET /api/foo1 возвращает представление (например, с помощью JSON) из foo1.
  • DELETE /api/foo1 удаляет foo1.

т.д.

Теперь позвольте мне сказать вам, что «Foo» является тип коллекции вещь. Поэтому я хочу, чтобы иметь возможность добавить «бар» на «Foo»:

  • PUT /api/foo1/bar3 добавляет bar3 к foo1.
  • GET /api/foo1/bar3 возвращает foo1.
  • DELETE /api/foo1/bar3 удаляет bar3 от foo1.
  • DELETE /api/foo1 удаляет foo1 в целом.

Теперь остается вопрос: что делает GET /api/foo1? Он просто возвращает представление foo1, как я изначально предполагал в этом вопросе? Или он возвращает список баров? Или он возвращает представление foo1, которое является описанием foo1, а также содержит список всех содержащихся в нем баров?

Или GET /api/foo1 просто возвращает представление foo1, как я предполагал в начале, и требуют PROPFIND запроса перечислить бруски внутри foo1 (подход, принятый WebDAV)? Но для того, чтобы быть последовательным, не нужно ли мне менять все мои другие функции типа списка до PROPFIND, что прямо противоречит всем этим тысячам учебных пособий RESTful, которые говорят, чтобы использовать список GET /api/foo1 для отображения содержимого?

ответ

2

Семантика webdav никогда не была согласована с идиомами интерфейсов RESTful.

Теоретически GET должен получать представление состояния ресурса, и PROPFIND должен использоваться для извлечения членов коллекции.

Таким образом, вы должны сделать это:

  • GET/апи/foo1/- возвращает состояние Foo1 только
  • PROPFIND/апи/foo1/- возвращает членов Foo1

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

Лично я использовать шлюз WebDAV/JSon, когда запросы сделаны с использованием RESTful идиомы, но маршрутизируется моей реализации Webdav

Например я хотел бы сделать это:

GET /api/foo1/_PROPFIND?fields=name,fooProp1,fooProp2 

И что бы вернуть

[ 
{ name : "bar1", fooProp1: "..", fooProp2 : ".."}, 
{ name : "bar2", fooProp1: "..", fooProp2 : ".."} 
] 

Одним из преимуществ такого подхода является то, что клиент получает возможность управления возвращаемыми свойствами json. Это хорошо, потому что богатый API будет обладать множеством свойств, но в большинстве случаев клиентам не нужны все из них.

1

Маршруты и их операции в RESTfull API полностью разработаны разработчиками. Разработчик, который решает, что вернуть, запрашивая конкретный маршрут, скажет: GET /api/foo1.

И разработчик должен проектировать каждый маршрут, включая /api/foo1/bar. Нет конкретного правила в отношении того, что должен делать конкретный маршрут. Если ваш API - проект с открытым исходным кодом, вы получите четкую и четкую документацию по каждому маршруту.

Не тратьте время на размышления о старых школьных стратегиях.

3

После некоторого размышления, я думаю, что лучшее концептуальное объяснение с точки зрения RESTful заключается в том, что обычно «вещь» - это не то же самое, что ее «коллекция». Таким образом, хотя в мире WebDAV directory/ может быть тем же самым, что хранит его файлы, в мире RESTful у меня может быть отдельный подкаталог directory/files/ для содержащихся файлов. Таким образом, я могу манипулировать каталогами отдельно от файлов, которые хранятся.

Рассмотрите RESTful API для фермы, которая содержит амбары. Конечная точка farm/api/barns/ может вернуть список амбаров, один из которых будет farm/api/barns/bigredbarn. Наивно я думаю, что получение farm/api/barns/bigredbarn/ предоставит мне список животных в сарае, что и вызвало этот вопрос.

Но на самом деле животные в сарае - это только один аспект Большого красного амбара. Он может содержать транспортные средства и сено:

  • farm/api/barns/bigredbarn/animals/
  • farm/api/barns/bigredbarn/vehicles/
  • farm/api/barns/bigredbarn/haybales/

При таком подходе дилемма я столкнулся не возникает.

+0

Мне нравится ваш подход. На самом деле, это то же самое поведение, которое действительно объектно-ориентированные языки реализовать для массива или списка объектов: массива свойств объекта: длина, размеров, ReadOnly метод Массива ПолучитьЗначения - возвращает элемент свойство объекта Списка: Голова, Текущий Метод списка GetEnumerator - возвращает объект, который в свою очередь возвращает элементы –

 Смежные вопросы

  • Нет связанных вопросов^_^