come implementare le chiamate al servizio web idempotente

8

Sto sviluppando una soluzione basata su wcf per un livello di servizio web che i dispositivi mobili "occasionalmente connessi" utilizzeranno. Il servizio non utilizzerà l'accodamento (in questa fase) a causa delle complessità aggiuntive, e quindi opererà invece un semplice approccio di richiesta / risposta.

Ovviamente, essendo un dispositivo mobile, è possibile che i dispositivi possano uscire dal mid insert / update del segnale. Il webservice stesso potrebbe aver completato la transazione, ma il client non riceverà mai questo messaggio. A causa di ciò, invierà nuovamente la richiesta, a quel punto il server dovrà riconoscerla come una richiesta duplicata e restituire la stessa risposta che ha provato nella prima istanza.

Quindi sto cercando di rendere i servizi idempotenti. Per raggiungere questo obiettivo, sto implementando oggetti DTO di Request Paramter, che sono costituiti dal RequestID, oltre ai parametri necessari per completare la chiamata.

Tuttavia, la mia difficoltà sta nell'implementare un modo di monitorare gli ID di richiesta. Dato che il servizio è attualmente senza stato, l'unico modo che posso immaginare è di avere una tabella ServiceRequest nel database, che prenderà il RequestID come primario. Ovviamente l'interrogazione su questo indicherà se la richiesta è già stata attivata, in quanto il client invierà lo stesso ID richiesta. Ma il servizio deve anche sapere quale messaggio inviare. Nel caso di un inserimento / aggiornamento, l'ID radice aggregato interessato dovrà anche essere memorizzato da qualche parte, sia direttamente sulla tabella delle richieste, sia in una tabella RequestToObjectLookup

Quindi, mi chiedo se c'è un modo migliore per implementarlo? I miei pensieri sono di avere una o più tabelle ServiceRequest (specifiche per il servizio), che memorizzano i richiedenti, informazioni aggiuntive e anche una ricerca per l'oggetto ID risultato (su un salvataggio / inserimento / aggiornamento). Quindi, quando arriva una nuova richiesta, questa tabella può essere consultata prima di procedere con il resto della richiesta, sia che si tratti di eseguire il salvataggio, o semplicemente di restituire l'oggetto precedentemente aggiornato (che è stato attivato al primo tentativo di richiesta).

Sto anche pensando (come detto) che ho solo bisogno di mantenere l'id di aggregazione di root referenziato con la richiesta, poiché dovrei solo essere in grado di utilizzare le relazioni per ottenere il resto delle informazioni.

    
posta Milambardo 04.11.2014 - 13:49
fonte

1 risposta

2

La cancellazione può essere resa idempotente consentendo solo l'eliminazione in base agli ID. Dovrai avere un modo per gli ID di rimanere "in uso" e magari scadere.

Con un tale sistema di prenotazione; la creazione di un oggetto può essere effettuata prenotando prima un ID e poi una seconda chiamata per creare l'oggetto con quell'ID (essenzialmente un aggiornamento sul nuovo oggetto vuoto). Quando viene richiesto un ID, il server acquisisce qualsiasi ID libero e crea un oggetto non inizializzato con tale ID, la seconda chiamata per l'inizializzazione includerà l'ID restituito in precedenza (più tutti i dati richiesti). Ciò significa che la seconda chiamata è essenzialmente una chiamata di aggiornamento che è idem potente di per sé (chiamarla con gli stessi dati più volte risulterà lo stesso risultato).

Se la prenotazione si verifica più volte, vengono restituiti più ID e l'oggetto inizializzato rimarrà. Questi oggetti non inizializzati possono essere ripuliti automaticamente da un rhoomba dopo un po 'di tempo.

Ciò impone al cliente di assicurarsi che, se ottengono un ID, è responsabile della chiamata all'inizializzazione. Se il client cade a metà della transazione, dovrebbe mantenere il proprio log per le operazioni in modo che sappia ad esempio che ha ottenuto un ID ed è stato impegnato con l'inizializzazione dell'oggetto.

L'aggiornamento è più difficile da rendere idempotente, ma una operazione di confronto e impostazione (con risultati true / false) aiuterà.

    
risposta data 04.11.2014 - 17:04
fonte

Leggi altre domande sui tag