java - tutorial - Qual è una buona strategia per convertire le entità jpa in risorse restful



java persistence api (3)

Con una combinazione di JAX_RS 1.1 e Jackson / GSON puoi esporre le entità JPA direttamente come risorse REST, ma ti imbatterai in una miriade di problemi.

Le DTO, ovvero le proiezioni sulle entità JPA, sono la strada da seguire. Ti permetterebbe di separare le preoccupazioni relative alla rappresentazione delle risorse di REST dalle preoccupazioni transazionali di JPA. Si arriva a definire esplicitamente la natura delle rappresentazioni. È possibile controllare la quantità di dati che appare nella rappresentazione, compresa la profondità del grafico dell'oggetto da attraversare, se si progettano attentamente i DTO / proiezioni. Potrebbe essere necessario creare più DTO / proiezioni per la stessa entità JPA per le diverse risorse in cui potrebbe essere necessario rappresentare l'entità in modo diverso.

Inoltre, nella mia esperienza di utilizzo di annotazioni come @JsonIgnore e @JsonIdentityInfo su entità JPA, non si prestano esattamente a rappresentazioni di risorse più utilizzabili. È possibile che si verifichino problemi quando si uniscono gli oggetti nel contesto di persistenza (a causa di proprietà ignorate), oppure i client potrebbero non essere in grado di utilizzare le rappresentazioni di risorse, poiché i riferimenti agli oggetti come schemi potrebbero non essere compresi. La maggior parte dei client JavaScript di solito ha problemi a consumare riferimenti a oggetti prodotti @JsonidentityInfo , a causa della mancanza di standardizzazione qui.

Ci sono altri aspetti aggiuntivi che sarebbero possibili attraverso DTO / proiezioni. JPA @EmbeddedId s non si adattano naturalmente alle rappresentazioni di risorse REST. Alcuni sostengono l'uso dell'annotazione JAX-RS @MatrixParam per identificare la risorsa in modo univoco negli URI delle risorse, ma questo non funziona @MatrixParam per la maggior parte dei client. Dopo tutto, i parametri della matrice sono solo una nota di progettazione e non uno standard (ancora). Con un DTO / proiezione, è possibile fornire la rappresentazione della risorsa rispetto a un ID calcolato (potrebbe essere una combinazione delle chiavi costitutive).

Nota: al momento lavoro sul plugin JBoss Forge per REST in cui esistono alcuni o tutti questi problemi e verrebbero risolti in alcune versioni future tramite la generazione di DTO.

Le risorse restful non hanno sempre un mapping one-to-one con le tue entità jpa. Per come la vedo, ci sono alcuni problemi che sto cercando di capire come gestire:

  1. Quando una risorsa ha informazioni che vengono popolate e salvate da più di un'entità.
  2. Quando un'entità ha più informazioni in essa che vuoi inviare come risorsa. Potrei semplicemente usare Jackson's @JsonIgnore ma avrei ancora problemi 1, 3 e 4.
  3. Quando un'entità (come una radice aggregata) ha entità nidificate e si desidera includere una parte delle sue entità nidificate ma solo un certo livello di nidificazione come risorsa.
  4. Quando si desidera escludere un pezzo di un'entità quando è parte di un'entità principale ma escludere un pezzo separato quando fa parte di un'entità padre diversa.
  5. Blasted riferimenti circolari (ho ottenuto questo principalmente lavorando con JSOG usando Jackson's @JsonIdentityInfo )

Possibili soluzioni: l'unico modo in cui potrei pensare che gestisse tutti questi problemi sarebbe quello di creare un intero gruppo di classi "risorsa" che avrebbero costruttori che hanno preso le entità necessarie per costruire la risorsa e mettere getter e setter necessari per quello risorsa su di esso. È eccessivo?

Per risolvere i problemi 2, 3, 4 e 5, potevo semplicemente eseguire alcune operazioni di pre e post sull'entità reale prima di inviarlo a Jackson per serializzare o deserializzare il mio pojo in JSON, ma questo non risolve il problema 1.

Questi sono tutti problemi che penserei che gli altri avrebbero incontrato e sono curioso di sapere quali soluzioni altre persone hanno escogitato. (Attualmente sto usando JPA 2, Spring MVC, Jackson e Spring-Data ma aperto ad altre tecnologie)


Dati i vostri vincoli, non sembra esserci altra soluzione rispetto agli oggetti di trasferimento dati - sì, si sta verificando abbastanza frequentemente che le persone hanno chiamato questo modello ...


Sono d'accordo con le altre risposte che i DTO sono la strada da percorrere. Risolvono molti problemi:

  1. Separazione di livelli e codice pulito. Un giorno potrebbe essere necessario esporre il modello di dati utilizzando un formato diverso (ad esempio XML) o un'interfaccia (ad esempio non basata sul servizio web). Mantenere tutte le configurazioni (come @JsonIgnore , @JsonidentityInfo ) per ogni interfaccia / formato nel modello di dominio renderebbe davvero disordinato. I DTO separano le preoccupazioni. Possono contenere tutte le configurazioni richieste dalla tua interfaccia esterna (servizio web) senza comportare modifiche nel modello di dominio, che possono mantenere il servizio web e la formattazione in modo agnostico.

  2. Sicurezza: puoi controllare facilmente ciò che è esposto al client e ciò che il client è autorizzato a modificare.

  3. Prestazioni: puoi controllare facilmente ciò che viene inviato al client.

  4. Problemi come i riferimenti alle entità (circolari), le raccolte caricate su pigramente vengono risolti esplicitamente e consapevolmente da voi durante la conversione in DTO.





jackson