2012-04-17 4 views
5

Esiste un modo RESTful per determinare se un POST (o qualsiasi altro verbo non idempotente) avrà esito positivo? Ciò sembra essere utile nei casi in cui è necessario eseguire più richieste di identriento su servizi diversi, ognuno dei quali potrebbe non riuscire. Sarebbe bello se queste richieste potessero essere fatte in una "transazione" (cioè con supporto per il rollback), ma poiché ciò è impossibile, un'alternativa è controllare se ognuna delle richieste avrà successo prima di eseguirle effettivamente. Ad esempio, suppongo che sto costruendo un sistema di e-commerce che consente alle persone di acquistare magliette con testo personalizzato stampato su di esse, e questo sistema richiede l'integrazione con due diversi servizi: un servizio di stampa su t-shirt e un servizio di pagamento . Ognuno di questi ha un'API RESTful e potrebbe non riuscire. (ad esempio, la tipografia potrebbe rifiutarsi di stampare determinate parole su una maglietta, per esempio, e la banca potrebbe lamentarsi se la carta di credito è scaduta.) Esiste un modo per eseguire speculativamente queste due richieste, quindi il mio sistema procederà solo con loro se entrambe le richieste sembrano valide?Esiste un modo RESTful per determinare se un POST avrà successo?

In caso contrario, questo problema può essere risolto in un modo diverso? Creazione di una risorsa tramite POST con status = pending e modifica a status = complete se tutte le richieste hanno esito positivo? (DELETE è più complicato ...)

+0

Un altro approccio: un 'POST' con' persist = false' o 'effimero = true'. (Sembra un po 'hacky, ma non richiede un successivo cambiamento di 'status' - quando si vuole veramente che il' POST' accada, emetterlo di nuovo.) – mjs

risposta

2

HTTP definisce il codice 202 di stato esattamente lo scenario:

202 accettate

La richiesta è stata accettata per l'elaborazione, ma l'elaborazione non è stata completata. La richiesta potrebbe o non potrebbe essere eventualmente presa in considerazione, in quanto potrebbe non essere consentita quando l'elaborazione ha effettivamente luogo. Non è possibile inviare nuovamente un codice di stato da un'operazione asincrona come questa.

La risposta 202 è intenzionalmente non impegnativa. Il suo scopo è quello di consentire ad un server di accettare una richiesta per qualche altro processo (magari un processo orientato ai batch che viene eseguito una volta al giorno) senza richiedere che la connessione dell'agente utente al server rimanga valida fino al completamento del processo. L'entità restituita con questa risposta DOVREBBE includere un'indicazione dello stato corrente della richiesta e un puntatore a un monitor di stato o una stima di quando l'utente può aspettarsi che la richiesta sia soddisfatta.

Fonte: HTTP 1.1 Status Code Definition

Questo è simile alla 201 Creato, salvo che si indica che la richiesta non è stata completata e l'entità non è ancora stato creato. La tua risposta conterrà un URL alla risorsa che rappresenta la "richiesta d'ordine", in modo che i clienti possano controllare lo stato dell'ordine tramite questo URL.


Per rispondere alla tua domanda in modo più diretto: Non c'è modo per "testare" se una richiesta riuscirà prima di farlo, perché stai chiedendo la chiaroveggenza.

Non è possibile prevedere la gamma di problemi tecnici che potrebbero verificarsi quando si tenta di effettuare una richiesta in futuro. La rete potrebbe non essere disponibile, il server potrebbe non essere in grado di accedere al suo database o ai sistemi esterni dipende dal funzionamento, potrebbe esserci un'interruzione di corrente e il server non è in linea, un neutrino vagante potrebbe vagare nella memoria ed urtare uno 0 a 1 causando un errore kernel catastrofico.

Per utilizzare un servizio remoto è necessario tenere conto di eventuali errori di qualsiasi richiesta in isolamento da altri processi.

Per il tuo problema specifico, se i servizi non hanno sicurezza transazionale, non è possibile utilizzare nessuno di questi e devi gestirli in un modo più realistico. Alcune opzioni al largo della parte superiore della mia testa:

  1. ottenere l'azienda T-shirt per darvi un meccanismo di "test", in modo da poter vedere se faranno elaborare qualsiasi ordine senza in realtà posizionarlo. Potrebbe essere che effettuare un ordine con loro è un'operazione a due fasi, in cui costruisci l'ordine nella prima fase (in cui viene convalidata la sua creazione) e successivamente richiedi l'elaborazione dell'ordine (dopo aver preso il pagamento con successo).

  2. Prima prendi il pagamento con carta di credito e sposta il tuo ordine in uno stato "a pagamento". Quindi provare a soddisfare l'ordine con il servizio T-Shirt come processo asincrono. Se l'adempimento fallisce e puoi identificare che il cliente ha cercato di ottenere qualcosa di stampato, la società non è pronta a produrre, dovrai contattarli per cambiare il loro ordine o produrre un rimborso.

La maggior parte delle organizzazioni adotterà il secondo approccio, grazie alla sua semplicità tecnica e al rischio ridotto per il business. Ha anche il vantaggio di essere in grado di far fronte al fatto che il servizio T-Shirt non è disponibile; il processo asincrono attende semplicemente che il servizio sia disponibile e completa l'ordine in quel momento.

+0

+1. Interessante che il codice 202 ... –

+0

Uh, scusa, volevo dire "non idempotente" (domanda aggiornata, anche se ripensandoci ora, la domanda si applica anche a "PUT", che è idempotente ...). Ad ogni modo, sono abbastanza sicuro che un 202 non è adatto ai miei scopi - è rilasciato dal * server *, indipendentemente da ciò che il cliente vuole. (Forse il cliente non può acquistare la maglietta, perché non ha una carta di credito valida.) – mjs

+0

Capito. Rimosso le mie parole sull'idempotenza. –

1

Esattamente. Questo può essere fatto come suggerisci nella tua ultima frase. L'idea sarebbe quella di decopolare la creazione di risorse (che funzionerà sempre a meno di guasti di rete) che rappresenta una "richiesta in corso" di "accettazione dell'ordine", che può essere successivamente decisa. Poiché POST restituisce un'intestazione "Location", puoi quindi recuperare in qualsiasi momento lo "stato" della tua richiesta.

A un certo punto può essere accettato o rifiutato. Questo potrebbe essere intestinale o potrebbe richiedere del tempo, quindi devi progettare il tuo servizio con queste restrizioni (cioè consentire al cliente di verificare se il suo ordine è accettato, o di eseguire una sorta di servizio orario/giornaliero che raccoglie richieste accettate) .