2015-04-14 26 views
6

Siamo in procinto di sviluppare un'applicazione Web con AngularJS, Rest, JPA. Ho letto alcuni articoli su come le entità di dominio non dovrebbero essere esposte tramite i servizi. Capisco che questo è un accoppiamento stretto, potrebbero esserci riferimenti circolari, separazione delle preoccupazioni e mi sembra valido. Ma poi vedo articoli sull'applicazione di entrambi i mapping jpa e jaxb allo stesso modello, eclipseLink moxy è un esempio.Esposizione di entità JPA tramite il servizio

Poi c'è REST dati Primavera che espone entità JPA tramite un API REST. (Può essere primavera dati REST viene utilizzato per risolvere un problema diverso a portata di mano)

quindi sono un po 'confuso. Risposte alle seguenti 2 domande e scenari in cui uno è meglio che l'altro sia utile.

  1. Quali sono i vantaggi nell'applicazione sia JAXB e le annotazioni JPA allo stesso modello di dominio? Questo è fatto principalmente per evitare un DTO tra i livelli ?

  2. I dati di primavera REST devono essere utilizzati solo quando si sviluppa un'applicazione che richiede l'esposizione di operazioni CRUD e non vi sono realmente altre funzionalità aziendali coinvolte?

risposta

1

L'utilizzo di DTO richiede un certo overhead: le classi DTO devono essere create; le classi di entità devono essere mappate al DTO prima della serializzazione.

DTO inoltre "si sente in errore" nella misura in cui sembra contravvenire al principio "non ripetersi". È frustrante guardare un'entità e un DTO e vedere che sono essenzialmente gli stessi.

Quindi, esporre direttamente le entità JPA riduce il codice e riduce l'overhead mentale mentre si lavora con il codice. I tuoi controller, servizi e repository si occupano tutti delle stesse classi.

Non ci sono problemi, però:

  • mancata corrispondenza tra le rappresentazioni interne e l'interfaccia si desidera esporre per l'utente API.

    Esempio reale: documenti gerarchici in cui il documento radice è un article e i documenti figlio sono sections. Internamente, ogni documento ha una relazione con un documento genitore che può essere nullo.

    Esporre questa entità direttamente tramite l'interfaccia REST richiederebbe al client di inviare id (o lo url in HATEOAS) come parte dell'entità inviata per collegare correttamente i documenti.

    Molto meglio è avere l'utente API POST a /articles/{id}/sections/ durante la creazione di una sottosezione.

  • Esposizione dati interni.

    Le entità possono includere identificatori, percorsi su disco, ecc. Che non sono realmente destinati al consumo pubblico. Dovrai eseguire @JsonIgnore durante la serializzazione. Quando deserializzi, dovrai anche riempirli manualmente dall'entità.

  • Prestazioni.

    Simile al punto precedente; forse la tua entità contiene un grande oggetto di dati. Vuoi che gli utenti siano in grado di POST o PUT questi, ma non dovrebbero essere richiesti per scaricare l'oggetto solo per leggere gli altri campi dell'entità.

  • Possibili problemi di serializzazione.

    Le collezioni pigre sono il classico caso di fallimento.

  • Rappresentazioni serializzate più complicate del necessario.

    Esempio di mondo reale: a word entità con una collezione di synonyms; i sinonimi dipendono dalla parola. Direttamente serializzazione delle entità si tradurrà in:

    { "id":12, 
        "word": "cat", 
        "synonyms": [ 
        { "id": 23, 
         "synonym": "kitty" 
        }, 
        { "id": 34, 
         "synonym": "pussycat" 
        } 
        ] 
    } 
    

    un modello migliore è:

    { "word": "cat", 
        "synonyms": [ 
        "kitty", 
        "pussycat" 
        ] 
    } 
    
  • sacco di annotazioni sulla stessa classe che può ridurre la chiarezza.

    A seconda della complessità entità, si potrebbe avere annotazioni APP (@Entity, @Id, @GeneratedValue, @Column, @ManyToMany, @MappedBy, ecc), le annotazioni XML (@XmlRootElement, @XmlType, @XmlElement, ecc), le annotazioni JSON (@JsonInclude, @JsonIgnore, @JsonProperty, ecc.) E annotazioni di convalida (@NotNull, @Null, ecc.) Tutti sulla stessa classe.

A causa di tutti questi problemi, generalmente utilizzo DTO. Faccio l'entità alla mappatura DTO a mano, ma ci sono progetti che cercano di renderlo più facile, come Dozer.

Posso immaginare di utilizzare spring-data-rest o di esporre direttamente le mie entità solo nel caso in cui disponga di entità molto semplici, senza troppe relazioni tra di loro e dove c'è un'alta corrispondenza tra il modello di entità e il modello che desideravo esporre all'utente.

+0

Non sono almeno alcune delle vostre preoccupazioni trattate da https://spring.io/blog/2014/05/21/what-s-new-in-spring-data-dijkstra#projections-in-spring- dati-rest –