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:
- Chiedo il riavvio.
- Il server risponde immediatamente con una pagina di stato.
- Il router avvia il riavvio.
- 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.
- Il router si riavvia e il server torna online.
- Alla successiva richiesta di stato, il server fornisce una risposta di stato riavviata e reindirizza il mio browser a una nuova pagina.