Связь и HATEOAS

Говорят, что в хорошо определенной системе RESTful клиентам нужно знать только корневой URI или несколько хорошо известных URI, и клиент должен обнаружить все остальные ссылки через эти начальные URI. Я понимаю преимущества (отдельные клиенты) от этого подхода, но недостатком для меня является то, что клиенту необходимо обнаруживать ссылки каждый раз, когда он пытается получить доступ к чему-либо, т.е. учитывая следующую иерархию ресурсов:

/collection1
collection1
  |-sub1
    |-sub1sub1
 |-sub1sub1sub1
         |-sub1sub1sub1sub1
    |-sub1sub2
  |-sub2
    |-sub2sub1
    |-sub2sub2
  |-sub3
    |-sub3sub1
    |-sub3sub2

Если мы будем следовать подходу «Клиенту нужно знать только корневой URI», то клиент должен знать только корневой URI, т.е. /коллекцию1 выше, а остальные URI должны быть обнаружены клиентами через гипермедийные ссылки. Я нахожу это громоздким, потому что каждый раз, когда клиенту нужно выполнить GET, скажем, для sub1sub1sub1sub1, клиент должен сначала выполнить GET для /collection1 и перейти по ссылке, определенной в возвращаемом представлении, а затем выполнить еще несколько GET для подресурсов, чтобы достичь желаемый ресурс? или мое понимание связности совершенно неверно?

С уважением, Суреш.


person Suresh Kumar    schedule 14.07.2010    source источник
comment
Просто служба REST не имеет состояния, клиент — нет. Таким образом, клиент может запомнить предыдущие ресурсы, их URL-адреса и т. д., например, с помощью вложенного меню навигации...   -  person inf3rno    schedule 15.11.2013


Ответы (3)


Вы столкнетесь с этим несоответствием, когда попытаетесь создать API REST, который не соответствует потоку пользовательского агента, использующего API.

Учтите, что когда вы запускаете клиентское приложение, пользователю всегда предоставляется некоторый начальный экран. Если вы сопоставите содержимое и параметры на этом экране с корневым представлением, то доступные ссылки и желаемые переходы будут хорошо совпадать. Когда пользователь выбирает параметры на экране, вы можете переходить к другим представлениям, и пользовательский интерфейс клиента должен быть обновлен, чтобы отразить новое представление.

Если вы попытаетесь смоделировать свой REST API как своего рода связанный репозиторий данных, а ваш клиентский пользовательский интерфейс — как независимый набор переходов, то вы обнаружите, что HATEOAS довольно болезненный.

person Darrel Miller    schedule 14.07.2010
comment
болезненно не обязательно верно: у меня есть только это, иерархия коллекций элементов, и клиент, когда он запускается, переходит на один или два уровня вниз и переходит к определенному пути (путь, который клиент использовал для иметь, когда он закрылся). Кэш клиента является постоянным, поэтому все запросы являются условными, и очень редко новые представления передаются по сети, а обновление может выполняться асинхронно в фоновом режиме, полностью работая с кешем. - person mogsie; 15.07.2010
comment
и я согласен с тем, что моделирование API в соответствии с требованиями клиентского приложения обеспечивает эффективную сессию, но я думаю, дело в том, что часто API должен обслуживать множество клиентов, а не только одного клиента. - person mogsie; 15.07.2010
comment
@mogsie Во многих случаях возможно создать API для нескольких клиентов, однако я думаю, что в большинстве случаев гораздо эффективнее создавать API для конкретного случая. Случайное повторное использование — это то, что должен обеспечить REST, а не обязательно запланированное повторное использование. - person Darrel Miller; 15.07.2010
comment
это правда. Допустим, Twitter создал настоящий RESTful API; они, вероятно, были бы в выигрыше, если бы использовали реальный или гипотетический клиент при разработке API. - person mogsie; 15.07.2010

Да, это правильно, что клиентское приложение должно проходить по ссылкам, но как только оно обнаружило ресурс, нет ничего плохого в том, чтобы сохранить ссылку на этот ресурс и использовать его в течение более длительного времени, чем один запрос. Если у вашего клиента есть возможность постоянно что-то помнить, он может это сделать.

подумайте, как веб-браузер хранит свои закладки. У вас, вероятно, есть десять или сотня закладок в браузере, и вы, вероятно, нашли некоторые из них глубоко в иерархии страниц, но браузер добросовестно запоминает их, не требуя запоминания пути, по которому они были найдены.

Более богатое клиентское приложение могло бы запомнить URI sub1sub1sub1sub1 и повторно использовать его, если он все еще работает. Вполне вероятно, что он по-прежнему представляет то же самое (так и должно быть). Если он больше не существует или не работает по какой-либо другой причине клиента (4xx), вы можете повторить свои шаги, чтобы увидеть, сможете ли вы найти подходящую замену.

И, конечно, то, что сказал Даррел Миллер :-)

person mogsie    schedule 14.07.2010
comment
Мне нравится ваша аналогия здесь. Есть такая идея, что все связано вместе, а то, что не связано, недостижимо. В этом смысле Google стал корнем всех навигации, но люди постоянно сохраняют ярлыки (закладки). Однако если вы не в гугле, то вас практически не существует. - person Alex; 10.12.2014
comment
Спасибо. Или, если быть более точным: если нет пути от Google к странице, ее не существует. Что-то вроде загадки: если в лесу падает дерево, и никто не слышит этого; шумит ли? - person mogsie; 17.12.2014

Не думаю, что это жесткое требование. Насколько я понимаю, клиент имеет право напрямую обращаться к ресурсам и начинать оттуда. Важно то, что вы не делаете этого для переходов между состояниями, то есть не переходите автоматически к /foo2 после работы с /foo1 и так далее. Первоначальное получение /products/1234 для редактирования выглядит вполне нормально. Сервер всегда может вернуть, скажем, редирект на /shop/products/1234, чтобы сохранить обратную совместимость (что желательно и для поисковых систем, и для закладок, и для внешних ссылок).

person dzuelke    schedule 14.07.2010