Sto costruendo un'API REST in cui i client possono interrogare i messaggi inviati dall'utente, in questo modo:
GET http://example.com/api/v1/messages?from=0&to=100
Risposta:
[
{
"id": 12345,
"text": "Hello, world!"
},
{
"id": 12346,
"text": "Testing, testing"
},
...
]
Ora, ho bisogno di includere il nome dell'utente che ha inviato il messaggio. Posso pensare a 4 modi per memorizzare queste informazioni, ma non riesco a decidere quale sia il migliore:
Opzione 1:
[
{
"id": 12345,
"sender_id": 16,
"text": "Hello, world!"
}
]
Questo metodo è il più efficiente su larga scala - se il client esegue una query sull'API molte volte, può memorizzare nella cache una mappa dell'ID utente per denominarla e riutilizzarla. Tuttavia, per le query una tantum, raddoppia la quantità di chiamate API che il client deve eseguire (una volta per l'elenco dei messaggi e un'altra per trovare il nome per un determinato ID utente).
Opzione 2:
[
{
"id": 12345,
"sender_name": "John Smith",
"text": "Hello, world!"
}
]
Questo metodo è il più semplice per il consumo del client, ma se l'API deve essere sempre modificata per includere l'ID del mittente (ad esempio per il collegamento da un messaggio all'altro), avrei bisogno di avere due campi "mittente" nell'oggetto messaggio, sender_id
e sender_name
, che è essenzialmente una versione peggiore dell'opzione 3.
Opzione 3:
[
{
"id": 12345,
"sender": {
"id": 16,
"name": "John Smith"
},
"text": "Hello, world!"
}
]
Questo approccio incorpora l'oggetto mittente in ciascun messaggio, che lo rende a prova di futuro e richiede solo una singola chiamata API per query. Tuttavia, aggiunge molte informazioni ridondanti se ci sono molti messaggi e pochi utenti (ad esempio, interrogando tutti i messaggi inviati da un singolo utente).
Opzione 4:
{
"users": [
{
"id": 16,
"name": "John Smith"
},
...
],
"messages": [
{
"id": 12345,
"sender_id": 16,
"text": "Hello, world!"
}
]
}
Questo risolve il problema della ridondanza con # 3, ma aggiunge molta complessità alla struttura dell'oggetto risposta.