Используйте полиморфный родительский подход.
@Controller
public class CommentsController {
@RequestMapping(value="/comments", method = RequestMethod.GET)
public @ResponseBody String index() {
/* kludge to allow optional path parameters */
return index(null, null);
}
@RequestMapping(value="/{parent_collection}/{parent_id}/comments", method = RequestMethod.GET)
public @ResponseBody String index(@PathVariable("parent_collection") String parentCollection, @PathVariable("parent_id") String parentId) {
if (parentCollection == null) {
return "all comments";
}
else if ((parentCollection != null) && (parentCollection.equals("posts"))) {
/* get parent, then get comments for parent */
return "comments for single post";
}
else if ((parentCollection != null) && (parentCollection.equals("customers"))) {
/* get parent, then get comments for parent */
return "comments for single customer";
}
else if ((parentCollection != null) && (parentCollection.equals("movies"))) {
/* get parent, then get comments for parent */
return "comments for single movie";
}
}
@RequestMapping(value = "/comments/{id}", method = RequestMethod.GET)
public @ResponseBody String show(@PathVariable Integer id) {
/* kludge to allow optional path parameters */
return show(null, null, id);
}
@RequestMapping(value = "/{parent_collection}/{parent_id}/comments/{id}", method = RequestMethod.GET)
public @ResponseBody String show(@PathVariable("parent_collection") String parentCollection, @PathVariable("parent_id") String parentId, @PathVariable Integer id) {
/* get comment, then get parent from foreign key */
if (parentCollection == null) {
return "single comment";
}
else if ((parentCollection != null) && (parentCollection.equals("posts"))) {
return "single comment for single post";
}
else if ((parentCollection != null) && (parentCollection.equals("customers"))) {
return "single comment for single customer";
}
else if ((parentCollection != null) && (parentCollection.equals("movies"))) {
return "single comment for single movie";
}
}
}
Кроме того, вы могли бы использовать базовый контроллер для маршрутизации префикса URI к родительским ресурсам (/libraries/{library_id}/../..
), добавить родительские модели в область запроса, а затем позволить обычным сопоставлениям запросов обрабатывать остальную часть URI дочерним ресурсам. (/../../books/1
). У меня нет такого примера.
Примечание. Отдельные вложенные ресурсы обычно рассматриваются как антипаттерны для дизайна URI. Контроллер должен обрабатывать свои собственные ресурсы. Наиболее распространенные реализации делают ключ для единственного вложенного ресурса уникальным, то есть не зависящим от его родительского ресурса. Например, первичный ключ записи базы данных. Однако существуют ситуации, когда ключ может быть не уникальным, например, порядковый номер или значение позиции (например, книга 1, глава 1, глава 2), или, возможно, даже естественный ключ (например, ISBN книги, SSN лица, адрес электронной почты). , имя пользователя, имя файла).
Пример канонических URI для вложенных ресурсов:
/articles
=> ArticlesController # index
/articles/1
=> ArticlesController # show
/articles/1/comments
=> CommentsController # index
/articles/1/comments/2
=> CommentsController # show (хорошо, но не предпочтительно)
/comments/2
=> CommentsController # show (предпочтительно)