Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return IDs in JSON response from Spring Data REST

I've got an entity

@Entity
@Table(name = "books")
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @Column(name = "id", unique = true, nullable = false)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column(name = "name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

I initialize it like this

@PostConstruct
public void init() {
    List<String> newFiles = this.listFiles();
    newFiles.forEach(filename -> {
        Book book = new Book();
        book.setName(filename);

        dbRepository.save(book);
    });
}

If I set the result of save to an instance of Book, I can get the id and it is not null—so id is created fine.

I defined a repository

@RepositoryRestResource
public interface IBooksRepository extends CrudRepository<Book, Long> {
}

which I'd like to use to get and set data into the books table in the database.

When I try to access my repository rest using curl localhost:8080/books, I get this response

{
   "_embedded":{
      "books":[
         {
            "name":"simple-file.txt",
            "_links":{
               "self":{
                  "href":"http://localhost:8080/books/1"
               },
               "book":{
                  "href":"http://localhost:8080/books/1"
               }
            }
         }
      ]
   },
   "_links":{
      "self":{
         "href":"http://localhost:8080/books"
      },
      "profile":{
         "href":"http://localhost:8080/profile/books"
      }
   }
}

The books element returns name only. How can I make it return id too, on the same level as name?

like image 206
lapots Avatar asked May 18 '17 11:05

lapots


People also ask

How do I return a JSON response from REST API?

To receive JSON from a REST API endpoint, you must send an HTTP GET request to the REST API server and provide an Accept: application/json request header. The Accept header tells the REST API server that the API client expects JSON.

What does the @RepositoryRestResource annotation do?

The @RepositoryRestResource annotation is optional and is used to customize the REST endpoint. If we decided to omit it, Spring would automatically create an endpoint at “/websiteUsers” instead of “/users“. That's it! We now have a fully-functional REST API.

What is @RepositoryRestController?

Annotation Type RepositoryRestControllerAnnotation to demarcate Spring MVC controllers provided by Spring Data REST. Allows to easily detect them and exclude them from standard Spring MVC handling.


2 Answers

Spring Data Rest hides the ID by default, in order to have it in the JSON you have to manually configure that for your entity. Depending on your spring version you can either provide your own configuration (old):

@Configuration
public class ExposeEntityIdRestConfiguration extends RepositoryRestMvcConfiguration {

    @Override
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(Book.class);
    }
}

...or register a RepositoryRestConfigurer (current):

@Component
public class ExposeEntityIdRestMvcConfiguration extends RepositoryRestConfigurerAdapter {

  @Override
  public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.exposeIdsFor(Book.class);
  }
}

See the Spring Data Rest documentation for more details.

like image 193
Ralf Stuckert Avatar answered Oct 15 '22 13:10

Ralf Stuckert


The accepted answer overrides a deprecated method. Here's the updated version:

@Component
public class RestConfig implements RepositoryRestConfigurer {

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
        config.exposeIdsFor(Book.class);
    }
}

An alternative approach is to implement RepositoryRestConfigurer in your @SpringBootApplication annotated class:

@SpringBootApplication
public class MyApplication implements RepositoryRestConfigurer {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Override
    public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
        config.exposeIdsFor(Book.class);
    }

}
like image 28
Domenico Avatar answered Oct 15 '22 11:10

Domenico