Sono stato alle prese con questo problema per un po '. Supponiamo che tu abbia un'applicazione aziendale con un dominio ricco e in una delle viste front-end tu mostri un elenco di Orders
aperto. In questa vista mostrate cose come orderDate, customerName, totalAmount, ... ma il client vuole anche vedere quanti oggetti sono nell'ordine (in pratica il conteggio dell'entità OrderItems). Qual è il modo migliore per gestirlo?
Ipotesi
- La classe
Order
ha unList<OrderItem>
che viene recuperato pigramente - Ogni oggetto ResponseDTO contiene solo le sue proprietà principali e qualsiasi proprietà da
@ManyToOne
associazioni (quindiCustomer
verrebbe incluso quando si preleva unOrder
Soluzione 1
Puoi effettuare una chiamata di riposo per la risorsa Order
chiamando /api/orders
, riceverai una risposta con le proprietà principali e i dati del cliente. Per ogni ordine dovrai eseguire un nuovo recupero fino a /api/orders/<id>/items
. Questo è fondamentalmente un problema N + 1 con molte chiamate HTTP.
Soluzione 2
Cambio il mio assunto iniziale e recupero avidamente le raccolte e includo immediatamente OrderItems
nel ResponseDTO. La domanda diventa quindi, sto andando a prendere con entusiasmo ogni collezione di ogni entità? Questo sembra un serio problema di prestazioni. In questa soluzione il front-end dovrebbe effettuare solo 1 chiamata.
Soluzione 3
Sono in gioco le ipotesi iniziali, quindi prendo pigramente le raccolte ma sposto il problema N + 1 dal front-end al back-end (quindi nessuna chiamata HTTP aggiuntiva), non una vera soluzione ma almeno il costoso HTTP le chiamate vengono eliminate.
Soluzione 4
Nel mio modello di dominio ricco aggiungo un attributo all'entità Order
chiamata numberOfItems
. Ogni volta che il metodo addOrderItem(OrderItem item)
viene invocato su un oggetto Order
, incremento l'attributo numberOfItems
. È anche memorizzato nel database. In questo modo posso avere tutte le mie ipotesi iniziali e utilizzare ResponseDTO solo con le proprietà principali e faccio solo 1 chiamata HTTP. Il problema che ho con questa soluzione è che molte persone dicono che non si dovrebbero archiviare dati aggregati come quelli nel database.
Capisco che non esiste una soluzione perfetta e dipende sempre, ma per la vita di me non riesco a trovare una buona discussione su questo problema. Quando si fa un problema su google, si trovano spesso informazioni su HATEOAS ma che si adatterebbero alla mia soluzione 1, che non credo sia davvero una soluzione.
Se qualcuno può dare una soluzione alternativa o migliorare una delle soluzioni che ho dato, sarebbe molto apprezzato.