Molte piccole richieste rispetto a poche grandi richieste (API Design)

39

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

  • Cliente : recupera i dati dal server principale tramite REST API.
  • 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, supponiamo che il cliente abbia bisogno di un elenco di elementi di ciascuna API di terze parti. Da questo elenco, verrà scelto un elemento a cui il cliente ha bisogno di vedere il contenuto completo dell'articolo e le risposte (cioè 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 elementi, uno per ottenere il contenuto principale per un elemento e uno per ottenere le risposte dell'articolo.

  • Pro: non faccio mai più richieste del necessario, le richieste dovrebbero essere piccole, quindi in genere dovrebbero essere più veloci.
  • Contro: devo fare molte richieste. Dopo aver scelto un elemento dall'elenco, l'utente potrebbe dover attendere prima di vedere il contenuto principale e quindi attendere ancora più a lungo per vedere 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 molto da attendere tra le chiamate poiché il mio server ha già i dati e deve solo alimentare il client.

  • Pro: ancora facile da implementare dal 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 che il client fa sempre una richiesta al server: dammi tutti i dati. Da qui è responsabilità del cliente salvare i dati e utilizzarli in modo appropriato.

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

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

    
posta williamg 24.02.2015 - 22:46
fonte

6 risposte

21

Una cosa da tenere a mente è la latenza di rete prevista (cioè 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 eseguiranno significativamente peggio di una grande.

Recentemente 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 LAN saltano dall'istanza del database e le prestazioni vanno bene.

Quando abbiamo iniziato per la prima volta con gli sviluppatori in India, hanno avuto tempi di attesa enormi all'avvio dell'applicazione e alla navigazione da pagina a pagina. Stiamo parlando di dieci minuti di attesa qui. Si è scoperto che questo era dovuto al fatto che il tempo di ping di ~ 200 ms dai loro banchi al nostro server di database di sviluppo veniva moltiplicato per molte, molte brevi query al database. Il mio ping locale da 0,5 ms è stato così banale che la chattiness 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 consisteva nel clonare il server del 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 verrà moltiplicata per il numero di comunicazioni attraverso il filo. La larghezza di banda una volta stabilita la connessione è in genere molto meno preoccupante.

    
risposta data 08.04.2015 - 16:07
fonte
1

Queste tre opzioni non si escludono a vicenda, è possibile utilizzare una combinazione di cache lato client e lato server. Tuttavia alcuni dati, come i commenti, potrebbero diventare obsoleti, se conservati nella cache per troppo tempo. Considerando che non è possibile verificare se questo è il caso, si dovrebbe probabilmente astenersi dal memorizzarlo affatto. D'altra parte il contenuto di solito non cambia drasticamente, quindi non ci sarebbe alcun danno nella cache sul lato server e quindi il precaricamento di alcuni di esso sul lato client per ridurre la latenza.

    
risposta data 26.03.2015 - 22:50
fonte
1

Basandosi solo sulle informazioni che hai dato, opzione 1, perché

  • con una sola richiesta del cliente potresti mescolare mele e arance e il cesto di frutta potrebbe essere molto grande.

  • la memorizzazione nella cache è un compromesso in cui guadagni prestazioni ma potenzialmente perde consistenza (dati obsoleti). Se non si verificano problemi di prestazioni identificati, i problemi di sincronizzazione di solito non valgono la pena.

risposta data 30.03.2015 - 12:34
fonte
0

Ho sempre trovato alcune grandi richieste per essere più performanti e più scalabili. Ma ci sono dei compromessi in tutti gli approcci, quindi dipende dalle esigenze del server e del client. Potresti voler usare un'altra opzione, che consiste nel richiedere al client di specificare un intero intervallo o una serie di dati da recuperare, non necessariamente tutti i dati, ma alcuni intervalli, che sono sintonizzati nel tempo per adattarsi alla larghezza di banda disponibile.

    
risposta data 25.02.2015 - 01:22
fonte
0

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

  • (A) quanto è grande il risultato di un singolo recupero totale
  • (B) quanti dettagli del risultato il client / utente userà tipicamente 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, vai per 2 (cache lato server) o anche 3 (cache lato client).

Per qualsiasi altra variazione A / B (grande / piccola), dovrai applicare discrezione. Fornisco spesso entrambi endpoint grossolani e fini per far fronte a casi d'uso diversi da clienti diversi.

    
risposta data 26.03.2015 - 14:49
fonte
0

Come sempre in programmazione, dipende.

Quindi, la vera domanda è: che 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 utilizzando. Ad esempio, dovresti considerare: Sono veloci o lenti? I dati cambiano frequentemente e in modo imprevisto? Sono "chiacchieroni" o riposano?

In caso di servizi veloci e facili da chiamare, con dati che cambiano così frequentemente che la cache lato server sta per creare problemi con la cache obsoleta, con tutti i mezzi, optare per l'opzione 1: più richieste, senza cache, solo quando necessario .

Se i tuoi dati esterni cambieranno in modo prevedibile, o se sei limitato all'utilizzo, o semplicemente puoi ottenere una migliore esperienza utente nella cache dei dati sul tuo server, vai su 2. Ma tieni presente che la cache è non libero: ha dei 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 mantieni una maggiore logica sul server, quindi rimango fermo per 1 o 2.

Solo il mio 2c.

    
risposta data 30.03.2015 - 12:17
fonte

Leggi altre domande sui tag