Mentre cerco di affrontare la possibilità di un errore quando invoco endpoint REST o in generale qualsiasi endpoint HTTP, mi chiedo se ci siano standard o pattern nelle specifiche HTTP o nel settore per affrontare il problema di determinare quando un'eccezione è transitoria e quando non è particolarmente utile ai fini della retryability.
Poiché un servizio remoto potrebbe fallire in qualsiasi momento, determinare quando dovremmo ritentare un'operazione deve essere una caratteristica fondamentale della nostra architettura distribuita.
- Ho iniziato considerando prima il metodo idempotency (ad esempio, get, put, delete è sicuro di riprovare in base ai nostri contratti di servizio).
- Poi ho preso in considerazione il codice di stato dove, ad es. 4xx non vengono riprovati, ma gli errori 5xx possono essere riprovati a seconda del tipo di errore, cioè se è transitorio o meno. Ad esempio, se il servizio remoto utilizza un database e ottengo un errore 5xx causato da un timeout della query, è possibile riprovare poiché la condizione è transitoria e il richiamo del servizio molto probabilmente riuscirà se riprovo. Tuttavia, potrebbero esserci altri tipi di errori che non sono transitori e che preferirei evitare di riprovare. Ad esempio, in passato abbiamo avuto degli errori causati da un DBA che aggiungeva un nuovo vincolo a una tabella e quindi un servizio che stava funzionando prima che iniziasse il fallimento con un errore non transitorio come una violazione del vincolo.
In passato, abbiamo commesso l'errore di ripetere all'infinito un errore di 500 pensando che fossero sempre transitori e che il servizio remoto alla fine si riprendesse e fosse in grado di gestire la richiesta. In particolare nelle interazioni da computer a computer (orchestrazioni) dove vorremmo evitare a tutti i costi la propagazione di un'eccezione poiché richiederebbe complesse transazioni di compensazione e la pubblicazione di richieste parzialmente elaborate in un DLQ per un successivo intervento umano.
In generale mi piacerebbe sapere come le persone del settore di solito si occupano di questo problema, in che modo questa proprietà di "transientness" viene trasmessa dal server al client utilizzando il protocollo HTTP.
Dovrei ricorrere all'utilizzo di codici di stato http personalizzati o dovrei comunicare questa proprietà in un'intestazione o in una proprietà del corpo?
Se esiste una soluzione standard per questo?
Sarebbe fantastico perché, se ci fosse, potrei aspettarmi che i servizi di terze parti consumino i miei servizi sapendo che si comporteranno correttamente e allo stesso tempo significa che potrei anche consumarli senza dover riconfigurare il mio protocollo per il loro particolare implementazione.
Accolgo con favore qualsiasi suggerimento sui protocolli di retryability per progettare buoni contratti di assistenza che mi aiutino a creare buoni cittadini del nostro ecosistema che potrebbero potenzialmente essere integrati con servizi di terze parti in futuro.
Finora sono particolarmente sbalordito nello scoprire che un modello di architettura distribuita come questa non fa della retryability un cittadino di prima classe, ma potrebbe essere che mi sbaglio nella mia interpretazione di come dovrebbe funzionare l'implementazione. Qualcuno può indicarmi la giusta direzione?