6

prima domanda qui, quindi sii gentile :)Spring Boot Rest Service, come ottenerlo per effettuare il marshalling dei collegamenti come proprietà?

Ho un progetto JPA che desidero esporre come REST. Ho fatto questo finora:

mia entità:

@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 
} 

Tutto bene, chiamo aggiunto primavera-boot-starter-dati-resto al mio pom e ora ricevo un servizio. Ecco il JSON che torno.

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! Praticamente quello che mi aspettavo. Ora chiamo il mio servizio usando Spring's RestTemplate e qui sono dove sono bloccato. Quando esegue il marshalling indietro nell'oggetto SignUpSheet estrae la maggior parte dell'oggetto, ma il campo ID è nullo (il che ha senso, perché non esiste un campo ID in Json, solo un riferimento automatico) e tutti gli oggetti OneToMany e ManyToOne sono null (presumo per lo stesso motivo).

La mia domanda è: come faccio a dire a Spring Hateoas di aggiungere l'ID al json o di dire a Jackson come portarlo sul campo ID? Inoltre come ottengo i collegamenti? Non dovrei eseguire il marshalling nell'entità JPA e creare invece un altro POJO per SignUpSheet (qualcosa che vorrei evitare a scopo di duplicazione ma che potrebbe essere discusso se è necessario/desiderabile per qualche motivo che mi manca). Ho aggiunto Jackson2HalModule al mio ObjectMapper ma sembra che non faccia alcuna differenza se è lì o no.

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

Grazie in anticipo per l'aiuto!

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

Soluzione:

primo passo, leggere il manuale :)

Così ho scoperto che ho bisogno di estendere ResourceSupport sulle mie DTOs appena creati. Fatto e fatto. Ma non ottenevo alcun link indietro! Sembra come se avessi bisogno di aggiungere la Jackson2HalModule all'oggetto Mapper sul RestTemplate in questo modo:

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

così ho dato io estendo off di RestTemplate e @Component e dovrei essere buono per qualsiasi hateoas risorsa.

risposta

3

Non penso che dovresti provare a deserializzare il JSON nella tua entità JPA. L'entità JPA è strettamente legata al database dell'applicazione e dovrebbe essere considerata un dettaglio dell'implementazione del server. Invece, consiglierei di mappare su un tipo specificamente modellato sull'API REST, non sulla struttura del database e sull'utilizzo di JPA.

Si sta utilizzando Spring Data REST che abbraccia fortemente hypermedia. Ciò significa che i client devono utilizzare gli URI per identificare risorse e collegamenti per navigare tra di loro. Ad esempio, sul lato client, un foglio di iscrizione ha già un ID; è il href del collegamento self nella risposta. Pertanto, non è necessario esporre l'ID dall'entità JPA. In effetti, così facendo si potrebbero esporre dettagli di implementazione della propria applicazione di cui i clienti non sono a conoscenza.

Piuttosto che cercare di popolare tutte le proprietà nella risposta, Spring Data REST fornisce invece i collegamenti.Ad esempio, per accedere al genitore di un foglio di iscrizione, è necessario estrarre il href del collegamento parent dalla risposta ed eseguire una richiesta GET sull'URI.

+0

Avevo la sensazione che il mio problema derivasse da un fraintendimento su come utilizzare Hypermedia. Quindi, quando creo gli oggetti in cui voglio effettuare il marshal, come posso ottenere i link? Creo variabili membro usando la classe Link? –

+0

Sì, sembra un approccio ragionevole. Potresti riutilizzare la classe 'Link' di Spring HATEOAS o crearne una tua. –

Problemi correlati