title: Spring Boot - RESTful controllers, hateoas and JSON
body: <p>So I went through some documentation and examples on using spring hateoas (with spring-boot). And so by following examples I have created 2 Controllers.</p>
  
  <p>Here is a snippet of the first one:</p>
  
  <pre><code>@RestController
  @RequestMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
  public class UserController {
      @Autowired
      private UserService userService;
  
      @RequestMapping(method = RequestMethod.GET)
      public HttpEntity&lt;Resources&lt;Resource&lt;UserResponse&gt;&gt;&gt; findAll() {
          List&lt;UserResponse&gt; userList = userService.finaAll();
  
          List&lt;Resource&lt;UserResponse&gt;&gt; resources = Lists.newArrayList();
          for (UserResponse user : userList) {
              Resource&lt;UserResponse&gt; userResource = new Resource&lt;UserResponse&gt;(user);
              resources.add(userResource);
              userResource.add(linkTo(methodOn(UserController.class).findAll()).withSelfRel());
              userResource.add(linkTo(methodOn(UserController.class).findById(user.getId())).withRel("viewUser"));
          }
  
          return new ResponseEntity(new Resources(resources), HttpStatus.OK);
      }
  }
  </code></pre>
  
  <p>And here is the UserResponse DTO:</p>
  
  <pre><code>public class UserResponse {
  
      private Long id;
  
      private String firstName;
  
      private String lastName;
  
      private String socialNumber;
  
      @JsonDeserialize(using = LocalDateDeserializer.class)
      @JsonSerialize(using = LocalDateSerializer.class)
      @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
      private LocalDate dateOfBirth;
  }
  </code></pre>
  
  <p>Getters and setters are removed for brevity the only thing that might be worth mentioning is that there is @JsonIgnore and @JsonProperty on getter/setter of ID attribute.</p>
  
  <p>Now the response I get is following:</p>
  
  <pre><code>{
    "_embedded" : {
      "userResponses" : [ {
        "firstName" : "Brand",
        "lastName" : "White",
        "socialNumber" : "342asd3423",
        "dateOfBirth" : "1987-04-04",
        "_links" : {
          "self" : {
            "href" : "http://localhost:8080/users"
          },
          "viewUser" : {
            "href" : "http://localhost:8080/users/10"
          }
        }
      }, {
        "firstName" : "Snow",
        "lastName" : "Green",
        "socialNumber" : "3423cxvx423",
        "dateOfBirth" : "1987-01-12",
        "_links" : {
          "self" : {
            "href" : "http://localhost:8080/users"
          },
          "viewUser" : {
            "href" : "http://localhost:8080/users/11"
          }
        }
      } ]
    }
  }
  </code></pre>
  
  <p>Question One: according to <a href="http://docs.spring.io/spring-hateoas/docs/current/reference/html/" rel="nofollow">http://docs.spring.io/spring-hateoas/docs/current/reference/html/</a> the format should be somethign along the lines: </p>
  
  <blockquote>
    <p>links : [ { rel : "self", href : "<a href="http://myhost/people" rel="nofollow">http://myhost/people</a>" } ] }
    in my example it looks like like "rel" is an attribute.</p>
  </blockquote>
  
  <p>I have a second controller which was basically copy pasted:</p>
  
  <pre><code>@RestController
  @RequestMapping(value = "/users/{userId}/details", produces = MediaType.APPLICATION_JSON_VALUE)
  public class DetailsController {
      //... services ...
      @RequestMapping(method = RequestMethod.GET)
      public HttpEntity&lt;Resources&lt;Resource&lt;DetailsResponse&gt;&gt;&gt; findAllUserDetails(@PathVariable("userId") Long userId) {
          Iterable&lt;UserDetails&gt; details = userDetails.findAll();
  
          List&lt;Resource&lt;DetailsResponse&gt;&gt; hyperList = Lists.newArrayList();
  
          for (UserDetails detail : details) {
              Resource&lt;DetailsResponse&gt; hyperRes = new Resource&lt;DetailsResponse&gt;(new DetailsResponse(details));
              hyperRes.add(linkTo(DetailsController.class, userId).withSelfRel());
              hyperRes.add(linkTo(DetailsController.class, userId).slash("/" + detail.getId()).withRel("viewDetail"));
              hyperRes.add(linkTo(DetailsController.class, userId).slash("/" + detail.getId()).withRel("updateDetail"));
  
              hyperList.add(hyperRes);
          }
  
          return new ResponseEntity(hyperList, HttpStatus.OK);
      }
  }
  </code></pre>
  
  <p>And this single method produces response like this:</p>
  
  <pre><code>{
      "lifespanDays": 60,
      "status": "deceased",
      "dateBorn": [
          2015,
          4,
          5
      ],
      "dateDied": [
          2015,
          6,
          4
      ],
      "links": [
          {
          "rel": "self",
          "href": "http://localhost:8080/users/10/details"
          },
          {
          "rel": "viewDetail",
          "href": "http://localhost:8080/users/10/details/30"
          },
          {
          "rel": "updateDetail",
          "href": "http://localhost:8080/users/10/details/30"
          }
      ]
  }
  </code></pre>
  
  <p>DTO for second controller:</p>
  
  <pre><code>public class UserDetailResponse {
  
      private Long lifespanDays;
  
      private String status;
  
      @JsonDeserialize(using = LocalDateDeserializer.class)
      @JsonSerialize(using = LocalDateSerializer.class)
      @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
      private LocalDate dateBorn;
  
      @JsonDeserialize(using = LocalDateDeserializer.class)
      @JsonSerialize(using = LocalDateSerializer.class)
      @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
      private LocalDate dateDied;
  }
  </code></pre>
  
  <p>I do not get it which format is correct for JSON ? And I also do not understand why they differ despite that the produces MediaType specified on the type is application/json for both. Plus the date format in the UserDetail response has also changed....</p>
  
  <p>Both controllers are under same package both are equally annotated. This is all out of the box Spring-Boot with bunch of stater dependencies:</p>
  
  <pre><code>compile('org.springframework.boot:spring-boot-starter-web:1.2.2.RELEASE')
  compile('org.springframework.hateoas:spring-hateoas:0.17.0.RELEASE')
  compile('org.springframework.boot:spring-boot-starter-data-rest:1.2.2.RELEASE') { transitive = true; }
  compile('com.google.code.gson:gson:2.3.1');
  compile('org.springframework.boot:spring-boot-starter-data-jpa:1.2.2.RELEASE') { transitive = true; };
  compile('com.google.guava:guava:18.0')
  compile('commons-beanutils:commons-beanutils:1.9.2')
  runtime('org.hsqldb:hsqldb:2.3.2');
  </code></pre>