Spring bootstrap service, how to make it marshal links as properties?

The first question here is so gentle :)

I have a JPA project that I want to show as REST. I have done it so far:

My essence:

@Entity public class SignUpSheet { @Id @GeneratedValue private Long id; @Column private String name; @Column private String description; @Column @Temporal(TemporalType.TIMESTAMP) private Date dateTime; @ManyToOne private User parent; @OneToMany private List<Volunteer> volunteers; //getter and setters } 

All is well and good, I call the added spring-boot-starter-data-rest in my pom, and now I get the service. Here is the JSON I am returning to.

 http://localhost:8080/api-0.1.0/signUpSheets/1 { "name": "Auction", "description": "My First Sign Up Sheet", "dateTime": "2015-04-22T03:47:12.000+0000", "volunteers": [ { "role": "Bringing stuff", "comments": "I have comments!" } ], "endpoint": "/signUpSheets", "_links": { "self": { "href": "http://localhost:8080/api-0.1.0/signUpSheets/1" }, "parent": { "href": "http://localhost:8080/api-0.1.0/signUpSheets/1/parent" }, "user": { "href": "http://localhost:8080/api-0.1.0/signUpSheets/1/user" } } } 

Super! Pretty much what I expected. Now I call my service using Spring RestTemplate and here where I am stuck. When it marshals back to the SignUpSheet object, it pulls most of the object, but the ID field is null (which makes sense because Json does not have an identifier field, just self-determination), and all OneToMany and ManyToOne objects are null (for the same reason).

My question is: How can I tell either Spring Hateoas to add an identifier to json, or tell Jackson how to marshal it ID in the ID field? Also, how do I get links? If I don’t march back to the JPA entity and instead create another POJO for SignUpSheet (which I would like to avoid for duplication purposes, but I could talk, if necessary / desirable for some reason I am missing). I have a Jackson2HalModule added to my ObjectMapper but it doesn't seem to matter if it is there or not.

 @Bean @Primary public ObjectMapper objectMapper() { ObjectMapper o = new ObjectMapper(); o.registerModule(new Jackson2HalModule()); return o; } 

Thanks in advance for your help!

==================================================== =====

Decision:

First step, read the manual :)

So, I found out that I need to extend ResourceSupport for my newly created DTO. Done and done. But I had no links! It seems I needed to add Jackson2HalModule to the mapper object in RestTemplate , like this:

  ObjectMapper o = new ObjectMapper(); o.registerModule(new Jackson2HalModule()); MappingJackson2HttpMessageConverter c = new MappingJackson2HttpMessageConverter(); c.setObjectMapper(o); restTemplate.getMessageConverters().add(0, c); 

So, I suppose I'm producing RestTemplate and @Component, and I should be good for any HATEOAS resource.

+6
source share
1 answer

I do not think you should try to deserialize JSON back into your JPA object. The essence of JPA is very closely related to your application database and should be seen as a detail of the server implementation. Instead, I would recommend mapping a type that is specifically modeled in the REST API, rather than the structure of your database and the use of JPA.

You are using Spring Data REST, which strongly covers hypermedia. This means that clients must use URIs to identify resources and links to move between. For example, on the client side, the registration sheet already has an identifier; this is the href self link in the answer. Therefore, there is no need to set the identifier from your JPA object. In fact, this will lead to the disclosure of implementation details of your application, which customers should not be aware of.

Instead of trying to populate all the properties in the response, Spring Data REST provides links. For example, to access the parent element, you must extract the href link from parent from the response and execute a GET request in the URI.

+3
source

Source: https://habr.com/ru/post/985978/


All Articles