Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind Spring Data REST entities to transfer objects?

We have two Spring Boot applications with a client-server architecture. The backend is configured with Spring Data REST + JPA. The front end should consume the resources exposed by the backend and serve a public REST api.

Is it possible to have Spring data map the domain objects automatically from DTOs by declaring, e.g., a mapper bean?

// JPA persistable
@Entity
public class Order { .. }

// Immutable DTO
public class OrderDto { .. } 

// Is this somehow possible..
@RepositoryRestResource
public interface OrderDtoRepository extends CrudRepository<OrderDto, Long> {}

// .. instead of this?
@RepositoryRestResource
public interface OrderRepository extends CrudRepository<Order, Long> {}
like image 219
RJo Avatar asked Sep 18 '14 07:09

RJo


People also ask

Is used for exposing spring data repositories over rest using spring data rest?

Spring Data REST can be used to expose HATEOAS RESTful resources around Spring Data repositories. Without writing a lot of code, we can expose RESTful API around Spring Data Repositories.

What does the @RepositoryRestResource annotation do?

@RepositoryRestResource is used to set options on the public Repository interface - it will automatically create endpoints as appropriate based on the type of Repository that is being extended (i.e. CrudRepository/PagingAndSortingRepository/etc).

Does spring data rest store associations in the database?

The association will not be stored in the database. That’s because Spring Data Rest simply puts a list of Address es into the Customer object and tells Hibernate to store it. Hibernate, however, only stores the associations in a bidirectional relationship if all Address es also know the Customer they belong to (also see this post on Stackoverflow).

What is the easiest way to work with spring data rest?

When working with Spring Data Rest, this implies that a Spring Data repository must exist for both entities. The easiest variant is also the cleanest and most maintainable. Address has a Customer field annotated with @ManyToOne.

How do I bind a parameter to a field in spring?

By default, Spring requires setter methods to bind HTTP parameters to fields. Fortunately, it’s possible to reconfigure the binder and use direct field access (via reflection). In order to configure the data binder globally for your whole application, you can create a controller advice component.

How is this Spring MVC tutorial managed on GitHub?

Each section of this tutorial is managed as a separate subproject in a single github repo: rest — Spring MVC + Spring HATEOAS app with HAL representations of each resource evolution — REST app where a field is evolved but old data is retained for backward compatibility


1 Answers

We can make use of Projection feature (available from 2.2.x onwards) in Spring Data REST. Something like below:

import org.springframework.data.rest.core.config.Projection;

@Projection(name = "orderDTO", types = Order.class)
public interface OrderDTO {
    //get attributes required for DTO
    String getOrderName();
}

@RepositoryRestResource(excerptProjection = OrderDTO.class)
public interface OrderRepository extends CrudRepository<Order, Long> {
}

When calling REST set "projection" parameter to "orderDTO" i.e

http://host/app/order?projection=orderDTO

Please refer:

  • https://github.com/spring-projects/spring-data-examples/tree/master/rest/projections/src
  • https://stackoverflow.com/a/23068719/1358551

Note:

  • By setting excerptProjection attribute in RepositoryRestResource annotation, it will return projection by default without "projection" parameter.
  • "projection" is required when we annotate the interface using @Projection and place it in the very same package as the domain type or a subpackage of it.
like image 123
charybr Avatar answered Jan 03 '23 15:01

charybr