Если подресурс имеет смысл только в контексте его родителя, то да, он должен быть возвращен вложенным в его родителя. Например, в HTML элемент <li>
сам по себе не имеет смысла как подресурс.
Однако, если ресурс может быть автономным, и вы захотите манипулировать ресурсом, независимым от любых других ресурсов, тогда он должен иметь свой собственный URI. Таким образом, вы можете выполнить POST или PUT для этого ресурса, не затрагивая другие связанные ресурсы, и без необходимости пересылать их обратно на сервер. Если вам приходилось манипулировать всем от родителя, подумайте о том, что произойдет, если один человек выполнит GET, изменит один подпункт, а затем выполнит PUT всего этого с измененным этим подпунктом; Что, если кто-то за это время поменяет кого-то другого? Затем вам нужно добавить блокировки и транзакционную семантику, которая победит полное отсутствие состояния REST.
По крайней мере, для запросов GET было бы неплохо иметь некоторую форму интерфейса массовых запросов, с помощью которого клиент может получать большое количество ресурсов одновременно; необходимость выполнения нового HTTP-запроса для каждого ресурса может занять много времени, так как это означает новый обход по сети для каждого GET. Может также иметь смысл массовое обновление функциональности. Но если вы хотите иметь возможность манипулировать одним ресурсом за раз, вам нужно предоставить URI для этого ресурса.
И да, совершенно нормально иметь более одного способа доступа к ресурсу. Вы можете думать об этом как о блоге; Вы можете получить истории на главной странице, или на страницах архива, или перейдя на их постоянную ссылку.
edit : Если вы хотите выполнить массовое обновление, не сталкиваясь с проблемой, когда один клиент передает устаревшие данные на сервер, у вас обычно есть два варианта:
- Замок . Один клиент сообщает серверу «Я хочу заблокировать весь этот набор данных», выбирает данные, которые он хочет изменить, изменяет данные, отправляет их обратно на сервер и разблокирует их.
- Оптимистичный параллелизм : клиент загружает набор данных, помеченный каким-либо тегом редакции, который сервер изменяет каждый раз, когда получает новые данные. Клиент изменяет его и отправляет обратно на сервер. Если за это время какие-либо другие данные в наборе были изменены, тег ревизии будет отсутствовать, и сервер ответит: «Извините, ваши данные устарели, попробуйте еще раз».
У каждого из них есть свои преимущества и недостатки. Проблема с блокировкой заключается в том, что она имеет состояние и поэтому не очень хорошо вписывается в архитектуру REST. Если клиентская программа падает или иным образом умирает, когда у нее есть блокировка, тогда эти данные будут постоянно заблокированы, если у вас нет какого-либо тайм-аута блокировки, что может быть сложно. Блокировка также может привести к тупиковой ситуации, если клиенты выполняют какие-то необычные транзакции, включающие несколько блокировок.
Проблема с оптимистичным параллелизмом заключается в том, что при высокой нагрузке на набор данных, когда множество клиентов изменяют его одновременно, может потребоваться много-много попыток, прежде чем данный клиент сможет опубликовать свои данные; на самом деле, медленный клиент может в конечном итоге быть полностью отрезанным от публикации обновлений, потому что другие клиенты постоянно меняют данные таким образом, что это означает, что медленные изменения клиентов всегда дают сбой.
Вам нужно будет решить для себя, какой из этих вариантов вам подходит. Эти проблемы также возникают при смене одного ресурса (одно обновление может заглушить другое), но когда вы объединяете ресурсы в массовый интерфейс, они будут появляться гораздо чаще. Вот почему я бы рекомендовал использовать два интерфейса, если вы собираетесь объединять ресурсы; тот, в котором ресурсы могут быть доступны по отдельности, и дополнительный массовый интерфейс, где много ресурсов могут быть прочитаны и записаны одновременно.