Announcement Announcement Module
Collapse
No announcement yet.
Spring MVC, REST, and HATEOAS Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring MVC, REST, and HATEOAS

    This is cross posted from StackOverflow as I am not getting much of a response over there...

    I'm struggling with the correct way to implement Spring MVC 3.x RESTful services with HATEOAS. Consider the following constraints:

    I don't want my domain entities polluted with web/rest constructs (if possible).
    I don't want my controllers polluted with view constructs (e.g. no knowledge JSON/XML/HTML/etc.).
    I want to support multiple views formats.

    Currently I have a nicely put together MVC app without HATEOAS. Domain entities are pure POJOs without any view or web/rest concepts embedded. For example:

    Code:
    class User {
       public String getName() {...}
       public String setName(String name) {...}
       ...
    }
    My controllers are also simple. They provide routing and status, and delegate to Spring's view resolution framework. Note my application supports JSON, XML, and HTML, yet no domain entities or controllers have embedded view information:

    Code:
    @Controller
    @RequestMapping("/users")
    class UserController {
    
      @RequestMapping
      public ModelAndView getAllUsers() {
        List<User> users = userRepository.findAll();
        return new ModelAndView("users/index", "users", users);
      }
    
      @RequestMapping("/{id}")
      public ModelAndView getUser(@PathVariable Long id) {
        User user = userRepository.findById(id);
        return new ModelAndView("users/show", "user", user);
      }
    }
    So, now my issue - I'm not sure of a clean way to support HATEOAS. Here's an example. Let's say when the client asks for a User in JSON format, it comes out like this:

    Code:
    {
      firstName: "John",
      lastName: "Smith"
    }
    Let's also say that when I support HATEOAS, I want the JSON to contain a simple "self" link that the client can then use to refresh the object, delete it, or something else:

    Code:
    {
      firstName: "John",
      lastName: "Smith",
      links: [
        {
          rel: "self",
          ref: "http://myserver/users/1"
        }
      ]
    }
    Somehow I want to attach links to my object. I feel the right place to do this is in the controller layer as the controllers all know the correct URLs. Additionally, since I support multiple views, I feel like the right thing to do is somehow decorate my domain entities in the controller before they are converted to JSON/XML/whatever in Spring's view resolution framework. One way to do this might be to wrap the POJO in question with a generic Resource class that contains a list of links. Some view tweaking would be required to crunch it into the format I want, but its doable. Unfortunately nested resources could not be wrapped in this way. Other things that come to mind include adding links to the ModelAndView, and then customizing each of Spring's out-of-the-box view resolvers to stuff links into the generated JSON/XML/etc. What I don't want is to be constantly hand-crafting JSON/XML/etc. to accommodate various links as they come and go during the course of development.

    Perhaps I should just embedded the concept of links in my domain model... feels wrong but would work.

    Thoughts from the Spring MVC + REST gurus?

  • #2
    Are there any solutions for this now?

    And what do you think about the overhead of all this absolute links?

    Comment


    • #3
      Have you come across the Spring Hateoas project? It is on GitHub (https://github.com/SpringSource/spring-hateoas) described as: "This project provides some APIs to ease creating REST representations that follow the HATEOAS principle when working with Spring and especially Spring MVC".

      It is quite a new project but you can get if from the public Maven repo if required:
      Code:
      <dependency>
          <groupId>org.springframework.hateoas</groupId>
          <artifactId>spring-hateoas</artifactId>
          <version>0.3.0.RELEASE</version>
      </dependency>
      Last edited by smithleej; Nov 30th, 2012, 07:55 AM.

      Comment

      Working...
      X