spring-bootspring-hateoasjson-api

Spring Hateos Json api list deserialise issue


I am working on using Spring Hateos Json api as a replacement for crnk. As per the documentation. I was able to get the expected response when I retrieve a object ie when I did

import static com.toedter.spring.hateoas.jsonapi.MediaTypes.JSON_API_VALUE;
import org.springframework.hateoas.EntityModel;

@RestController
@RequestMapping(value ="/cont, produces = JSON_API_VALUE)
public class MovieController {
    @RequestMapping("/getMovie",produces = JSON_API_VALUE)
    Public ResponseEntity<EntityModel<Movie>> getMovie(){
    EntityModel model=EntityModel.of(new Movie("1","first movie"));
    return model;
    
}

I am using following dependencies of Hateos and jsonapi

implementation 'org.springframework.boot:spring-boot-starter'
implementation 'com.toedter:spring-hateoas-jsonapi:2.1.3'
implementation 'org.springframework.boot:spring-boot-starter-hateoas'

and I get the expected response ie

{
  "data": {
    "id": "1",
    "type": "movies",
    "attributes": {
      "title": "Star Wars"
    }
  }
}

Now I need to get the List of Movies something like.

@RequestMapping("/getMovieList",produces = JSON_API_VALUE)
public List<EntityModel<Movie>> getMovieList(){

  EntityModel model1=EntityModel.of(new Movie("1","first movie"));
  EntityModel model2=EntityModel.of(new Movie("2","second movie"));
  List<EntityModel<Movie>> list=new ArrayList();
  list.add(model1);
  list.add(model2);
  return list;
}

I tried multiple ways but still could not get the attributes, I either get error or I don't get attributes


Solution

  • That is what the CollectionModel, as the name implies, is for and not EntityModel which is for single entities.

    @RequestMapping("/getMovieList",produces = JSON_API_VALUE)
    public CollectionModel<Movie> getMovieList(){
      var movies = List.of(new Movie("1", "first movie"), new Movie("2", "second movie"));
      return CollectionModel.of(movies);       
    }
    

    or you could use the wrap method which would also introduce the EntityModel in between.

    @RequestMapping("/getMovieList",produces = JSON_API_VALUE)
    public CollectionModel<EntityModel<Movie>> getMovieList(){
      var movies = List.of(new Movie("1", "first movie"), new Movie("2", "second movie"));
      return CollectionModel.wrap(movies);       
    }
    

    Depending on what you need for the response one of these 2 should work.