Come decidere se un'API dovrebbe essere sincrona o asincrona?

1

Sto sviluppando un servizio che esporrà alcune API attraverso il punto finale REST. Ho alcune API che possono richiedere molto tempo, ad esempio da 5 a 10 minuti, per completare l'operazione richiesta.

Sto anche scrivendo l'applicazione lato client che è multi-thread e può fare più richieste al server allo stesso tempo. Se l'API del server risulta sincrona, è comunque necessario che quel particolare thread client si blocchi in attesa della risposta dal server. Quindi, il client non è completamente bloccato, può continuare con altre operazioni.

Capisco che se lo faccio in modo asincrono, devo fare ancora un po 'di lavoro per la gestione dello stato dell'operazione dell'API, fornendo al client il modo per ottenere lo stato dell'operazione.

Detto questo, non sono ancora in grado di decidere se rendere questa API server sincrona o asincrona.

Su quali basi si decide di rendere un'API sincrona o asincrona? Dipende da quanto durerà l'operazione API? Dipende se il client può gestire la chiamata di blocco?

    
posta Toka 24.10.2018 - 22:45
fonte

2 risposte

5

HTTP è sincrono nel senso che ogni richiesta ottiene una risposta, ma asincrona nel senso che le richieste richiedono molto tempo e che più richieste possono essere elaborate in parallelo. Pertanto, molti client e server HTTP vengono implementati in modo asincrono, ma senza offrire un'API asincrona. L'utilizzo di più thread è un modo per implementare l'asincronicità, ma ce ne sono altri come callback o loop di eventi.

Se si desidera un'API asincrona con HTTP nel senso che una risposta non è immediatamente disponibile, è necessario modellare esplicitamente l'asincronia:

  • Quando viene ricevuta una richiesta valida, il server risponde immediatamente con uno stato di successo, molto probabilmente 202 Accettato o 303 Vedi Altro.
  • Il backend quindi lavora sul lavoro in background (magari come thread separato, forse come server separato).
  • La risposta dovrebbe descrivere come monitorare lo stato del lavoro e come recuperare il risultato. Successivamente, il cliente può utilizzare queste informazioni per recuperare il risultato.

Ci sono un paio di tecniche come il polling lungo o il trasferimento chunked per spingere il risultato non appena è disponibile da quella risorsa, ma generalmente richiede la cooperazione con il cliente.

L'alternativa è utilizzare un protocollo diverso da HTTP, in particolare un protocollo in cui i messaggi non hanno bisogno di una risposta. All'interno dello stack Web, i WebSocket sono un tale protocollo e consentono al server di inviare una risposta in un secondo momento. Tuttavia, l'utilizzo di tali protocolli implica uno sforzo di sviluppo più pesante per te perché le API non HTTP mancano di tooling e supporto framework.

Poiché le API asincrone sono più complicate per tutte le persone coinvolte, dovrebbero essere evitate. Di nuovo, non sono necessari per avere client o server asincroni. La modellazione dell'asincronicità nella tua API è appropriata quando:

  • la richiesta avvia un processo in background che può essere o non essere elaborato rapidamente o
  • la creazione della risposta richiede un certo tempo o
  • non puoi garantire che una risposta sia pronta prima che il client vada in timeout, probabilmente nell'ordine da 10 a 30 secondi.

Ad esempio, l'interfaccia web del mio router WiFi può riavviare il router. Ciò richiede intrinsecamente del tempo. Lo hanno implementato nel seguente modo asincrono:

  1. Chiedo il riavvio.
  2. Il server risponde immediatamente con una pagina di stato.
  3. Il router avvia il riavvio.
  4. La pagina di stato richiede continuamente lo stato in background. La maggior parte delle volte, la richiesta scade perché il server non è ancora stato riavviato.
  5. Il router si riavvia e il server torna online.
  6. Alla successiva richiesta di stato, il server fornisce una risposta di stato riavviata e reindirizza il mio browser a una nuova pagina.
risposta data 24.10.2018 - 23:21
fonte
1

Come regola generale, una richiesta HTTP dovrebbe girare in pochi millisecondi, non minuti. Non dovresti conoscere e non preoccuparti dei dettagli di implementazione del client e quindi di come potrebbero essere in grado o non essere in grado di gestire le richieste parallele. Il problema più grande con richieste lunghe diverse minuti è che in realtà è necessario "tenere la linea" per tutto questo tempo. Questo potrebbe essere difficile per diversi motivi:

  • I timeout e le interruzioni di rete possono interrompere la richiesta.
  • Il client non deve chiudere o annullare la richiesta, che può essere difficile per alcuni clienti, ad es. non è la modus operandi predefinita per PHP.
  • Rende più difficile la gestione di molte richieste in parallelo per il client in quanto ha effettivamente bisogno di allocare e conservare risorse per ogni richiesta che effettua e non può rilasciare la risorsa richiesta fino a quando il server non ha completato il lavoro.

Una volta che la richiesta è stata interrotta per qualsiasi motivo, non è possibile per il client ottenere il risultato dell'operazione e deve riavviare lo stesso processo, probabilmente di nuovo in attesa di alcuni minuti, causando un ciclo di errore.

Progettare l'API come asincrono rende questo molto più robusto. Il cliente può memorizzare un ID di lavoro ovunque desideri ed è libero di fare altre cose. Può controllare in qualsiasi momento che è conveniente per il cliente. Non importa se una singola richiesta fallisce per qualsiasi ragione, ogni operazione può essere ripetuta senza perdita di stato.

    
risposta data 25.10.2018 - 02:28
fonte

Leggi altre domande sui tag