Molte piccole richieste vs. poche grandi richieste (Progettazione API)


49

Attualmente sto lavorando a un progetto con un'organizzazione come segue:

  • Client : ottiene i dati dal server principale tramite API REST.
  • Server : richiede dati da vari altri server tramite API di terze parti
  • API di terze parti - Servizi fuori dal mio controllo che forniscono dati al server (Reddit, Hackernews, Quora, ecc.)

Per ragioni di argomento, supponiamo che il client abbia prima bisogno di un elenco di elementi da ciascuna delle API di terze parti. Da questo elenco, verrà scelto un elemento nel momento in cui il cliente deve vedere l'intero contenuto dell'articolo nonché le risposte (ovvero i commenti) all'elemento. Sto cercando di decidere tra tre opzioni:

A la carte

In questo approccio, avrei 3 endpoint separati sul mio server: uno per ottenere l'elenco degli articoli, uno per ottenere il contenuto principale per un articolo e uno per ottenere le risposte dell'articolo.

  • Pro: non faccio mai più richieste del necessario, le richieste dovrebbero essere piccole, quindi generalmente dovrebbero essere più veloci.
  • Contro: devo fare molte richieste. Dopo aver scelto un elemento dall'elenco, l'utente potrebbe dover attendere prima di visualizzare il contenuto principale e quindi attendere ancora di più per visualizzare le risposte

Cache lato server

In questa richiesta, farei una singola chiamata al mio server per "recuperare" tutti i dati per tutte le fonti. I dati verrebbero quindi memorizzati nella cache sul server. Il client avrebbe quindi gli stessi endpoint REST di prima, tranne che non ci sarebbe molta attesa tra le chiamate poiché il mio server ha già i dati e deve solo inviarli al client.

  • Pro: ancora facile da implementare sul lato client, ma senza problemi di latenza
  • Contro: un po 'più coinvolto lato server e la prima chiamata potrebbe richiedere davvero molto tempo.

Cache lato client

Questo scenario è simile al precedente, tranne per il fatto che il client fa una sola richiesta al server: dammi tutti i dati. Da qui è responsabilità del cliente salvare i dati e utilizzarli in modo appropriato.

  • Pro: implementazione del server semplice, molto veloce dopo la prima chiamata
  • Contro: la prima chiamata sarà molto lenta, più complicata implementazione sul lato client

Non sono sicuro di quale sia l'approccio migliore o se forse mi manca la soluzione ovvia. Qualsiasi consiglio sarebbe molto apprezzato!


Questa mi sembra una scelta tra freschezza e velocità. Cosa preferiscono le parti interessate e gli utenti finali?
Erk,

Risposte:


28

Una cosa da tenere a mente è la latenza di rete prevista (ovvero il tempo di ping) tra i client e il server. In una situazione di latenza elevata con larghezza di banda altrimenti buona, molte piccole richieste avranno prestazioni significativamente peggiori di una grande.

Di recente ho collaborato a un progetto di applicazione Web supportato da database multi-team in cui uno dei team è in India (il resto è negli Stati Uniti). Abbiamo una singola istanza di database ospitata nel nostro ufficio negli Stati Uniti a cui gli sviluppatori collegano le nostre istanze di server web locali. La mia scrivania è a una quindicina di metri e due salti LAN dall'istanza del database e le prestazioni vanno bene.

Quando abbiamo iniziato le cose con gli sviluppatori in India, stavano vivendo enormi tempi di attesa nell'avvio dell'applicazione e nella navigazione da una pagina all'altra. Stiamo parlando di tempi di attesa di dieci minuti qui. Si scopre che ciò è dovuto al fatto che il tempo di ping di circa 200 ms dai loro desk al nostro server di database dev veniva moltiplicato per molte, molte brevi query nel database. Il mio ping locale da 0,5 ms era così banale che la confusione tra server Web e server di database non ha mai avuto importanza. Questa è stata la prima volta che abbiamo avuto una separazione geografica tra server web e server di database.

La soluzione nel nostro caso è stata quella di clonare il server di database e sostenerne la copia in India, ma il punto qui è tenere presente che se il client e il server sono distanti, la latenza della rete sarà moltiplicata per il numero di comunicazioni attraverso il filo. La larghezza di banda una volta stabilita la connessione è in genere molto meno preoccupante.


2

Queste tre opzioni non si escludono a vicenda, è possibile utilizzare una combinazione di cache sia lato client che lato server. Tuttavia, alcuni dati, come i commenti, possono diventare obsoleti, se conservati nella cache per troppo tempo. Considerando che non è possibile verificare se è così, probabilmente si dovrebbe astenersi dal conservarlo affatto. D'altra parte, il contenuto di solito non cambia drasticamente, quindi non ci sarebbe nulla di male nel memorizzarlo nella cache sul lato server e quindi nel prenderne parte sul lato client per ridurre la latenza.


1

Basato solo sulle informazioni fornite, opzione 1, perché

  • con una singola richiesta del cliente mescoleresti mele e arance e il cesto di frutta potrebbe essere molto grande.

  • la memorizzazione nella cache è un compromesso in cui si ottengono prestazioni ma si perde potenzialmente coerenza (dati non aggiornati). Se non si riscontrano problemi di prestazioni identificati, in genere non vale la pena rischiare problemi di sincronizzazione.


0

Ho sempre trovato alcune grandi richieste di prestazioni migliori e più scalabili. Ma ci sono compromessi in tutti gli approcci, quindi dipende dalle esigenze del server e del client. È possibile che si desideri utilizzare un'altra opzione, ovvero fare in modo che il client specifichi un intero intervallo o un insieme di dati da recuperare, non necessariamente tutti i dati, ma un intervallo, che viene ottimizzato nel tempo per adattarsi alla larghezza di banda disponibile.


0

Vorrei (quasi) scontare l'opzione 3. La scelta tra 1 e 2 dipende da due cose:

  • (A) quanto è grande il risultato di un singolo recupero totale
  • (B) la quantità di dettagli del risultato che il cliente / utente utilizzerà in genere in quella sessione.

È facile prendere una decisione se A e B sono estremi:

  • Se A è grande e B piccolo, scegli l'opzione 1 (A la Carte).
  • Se A è piccolo e B è grande, selezionare 2 (cache lato server) o anche 3 (cache lato client).

Per qualsiasi altra variazione A / B (grande / piccola), dovrai applicare la discrezione. Fornisco spesso endpoint sia grossolani che fini per soddisfare diversi casi d'uso di diversi clienti.


0

Come sempre in programmazione, dipende.

Quindi, la vera domanda è: cosa dovresti considerare quando decidi per A / B / C o una combinazione dei tre?

Direi che i veri fattori discriminanti sono i dettagli di implementazione delle API di terze parti che stai consumando. Ad esempio, dovresti considerare: sono veloci o lenti? I dati cambiano frequentemente e inaspettatamente? Sono "loquaci" o Riposo?

In caso di servizi veloci e facili da chiamare, con i dati che cambiano così frequentemente che la cache lato server creerà problemi di cache obsoleta, in ogni caso, scegli l'opzione 1: più richieste, nessuna cache, solo quando necessario.

Se i tuoi dati esterni cambieranno in modo prevedibile, o se sei limitato con l'utilizzo, o semplicemente puoi ottenere una migliore esperienza utente memorizzando i dati nella cache sul tuo server, vai con 2. Ma tieni presente che la cache non è gratuita: ha costi in termini di debug e talvolta gli utenti si lamentano di non vedere gli aggiornamenti.

Opzione 3, prenderei in considerazione solo se i dati non sono molti, ma in tal caso anche le opzioni 1 o 2 possono funzionare e manterrai più logica sul server, quindi mi atterrerei per 1 o 2.

Solo il mio 2c.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.