Announcement Announcement Module
Collapse
No announcement yet.
Advice on REST style Controllers. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Advice on REST style Controllers.

    Hi all,

    I am relatively new to spring & spring @MVC. I am trying to suport REST style URLs for my resources and am having a real hard time trying to figure out the mapping.
    Consider a resource blog. As I understand it, for a proper rest style interface to it, I'd have to support the following:

    /blogs[GET] -> List of blog items
    /blogs/new[GET] -> New blog item form
    /blogs[POST] -> Create new blog item
    /blogs/<id>[GET] -> view blog item [id]
    /blogs/<id>/edit[GET] -> Edit blog item form for [id]
    /blogs/<id>[PUT] -> Save blog item from edit for [id]
    /blogs/<id>[DELETE] -> delete blog item [id]

    >> First attempt
    Code:
    @Controller
    @RequestMapping("/blogs")
    public class BlogsController {
      @RequestMapping(method = RequestMethod.GET)
      public String list() {..}
      @RequestMapping(value="/new", method = RequestMethod.GET)
      public String newItem(ModelMap map) { map.add("item", new Blog()); }
      @RequestMapping(method = RequestMethod.POST)
      public String create(@ModelAttribute("item") Blog blog, BindingResult result, ModelMap map) {...}
      @RequestMapping(value="/{id}", method = RequestMethod.GET)
      public String edit(@PathVariable String id, ModelMap map) { map.add("item", findItem(id)); }
      @RequestMapping(value="/{id}", method = RequestMethod.PUT)
      public String update(
        @PathVariable String id, 
        @ModelAttribute("item") Blog blog, 
        BindingResult result, ModelMap map) {...}
      @RequestMapping(value="/{id}", method = RequestMethod.DELETE)
      public String update(@PathVariable String id) {...}
    }
    Ok, hit problem. If I use SessionAttributes to store "item" across newItem and create (or edit/update) then list has a problem, if I don't then create (or update) can't bind to the model attribute. also the id in update seems superflous.

    Ok, read here, that I split this across controllers (Bad, but ok, let's go with it)...
    So now I have a separate EditBlogsController like:
    Code:
    @Controller
    @SessionAttributes("item")
    public class EditBlogsController {
    // new, create, edit, update methods
    }
    However, here I hit the same problem as the OP, in that Spring MVC is unable to deal with RequestMethod overloading (create() and list() methods will conflict) across multiple controllers.

    I am keenly aware that I could be
    a) completely mistaken about how things work
    b) ignorant of facilities available to me to make this work

    But I've been pouring over the documentation and experimenting to no avail.

    Could somebody please guide me or point me to documentation that could help.

    /thanks

  • #2
    The reference documentation is the only documentation. You also can find some helpful information on the Spring team blog site.

    I am also working on a RESTful controller approach. After working on some cases, I find that I shall not use a pure REST style for the reason that REST is for a stateless environment while a web application shall not be stateless. If I want a pure REST URLs in my application, I need pull some data from the session to the view layer such as JSP. That creates some unnecessary complexities. The conversation scope will be introduced in the next major release. REST might not be a good fit in the conversation scope.

    In terms of implementation, I run into a problem that I can't have the RequestMapping on the class as well as on methods which is similar with your sample of combing creation and edition in a single controller class.

    Comment


    • #3
      Success!

      Not sure what I did wrong in my first attempt to think it doesn't work, but I was mistaken. The template below works perfectly fine!

      Code:
      @Controller
      @RequestMapping("/blogs")
      @SessionAttributes("item")
      public class BlogsController {
        @RequestMapping(method = RequestMethod.GET)
        public String list() {..}
        @RequestMapping(value="/new", method = RequestMethod.GET)
        public String newItem(ModelMap map) { map.add("item", new Blog()); }
        @RequestMapping(method = RequestMethod.POST)
        public String create(@ModelAttribute("item") Blog blog, BindingResult result, ModelMap map) {...}
        @RequestMapping(value="/{id}", method = RequestMethod.GET)
        public String show(@PathVariable String id, ModelMap map) { map.add("item", findItem(id)); }
        @RequestMapping(value="/{id}/edit", method = RequestMethod.GET)
        public String edit(@PathVariable String id, ModelMap map) { map.add("item", findItem(id)); }
        @RequestMapping(value="/{id}", method = RequestMethod.PUT)
        public String update(
          @PathVariable String id, 
          @ModelAttribute("item") Blog blog, 
          BindingResult result, ModelMap map) {...}
        @RequestMapping(value="/{id}", method = RequestMethod.DELETE)
        public String update(@PathVariable String id) {...}
      }

      Comment

      Working...
      X