Domanda

Mi chiedo come si attuerebbe il seguente caso d'uso nel RESTO.È anche possibile fare senza compromettere il modello concettuale?

Leggere o aggiornare più le risorse nell'ambito di una singola transazione.Per esempio, il trasferimento di $100 da Bob conto in banca in Giovanni account.

Per quanto posso dire, l'unico modo per implementare questo è barare.Si potrebbe POSTARE la risorsa associati con Giovanni o Bob e effettuare l'intera operazione utilizzando una singola transazione.Per quanto mi riguarda, questa si rompe il RESTO architettura perché sei essenzialmente tunneling una chiamata RPC attraverso POST, invece di operativo sulle risorse individuali.

È stato utile?

Soluzione

Prendere in considerazione un soggiorno carrello scenario.Il carrello è concettualmente la transazione wrapper.Nello stesso modo che è possibile aggiungere più elementi a un carrello e poi inviare il paniere di elaborare l'ordine, è possibile aggiungere l'account di Bob voce per la transazione wrapper e poi Bill voce di account per il wrapper.Quando tutti i pezzi sono a posto, allora si può POST/METTERE la transazione wrapper con tutte le parti componenti.

Altri suggerimenti

Ci sono alcuni casi che non trovano risposta in questa domanda, che penso che è troppo male, perché ha un alto posizionamento su Google per i termini di ricerca :-)

In particolare, un bel correttamente sarebbe:Se si POSTA due volte (perché alcune cache hiccupped intermedio) si dovrebbe trasferire la quantità due volte.

Per arrivare a questo, si crea una transazione come un oggetto.Questo potrebbe contenere tutti i dati che si conoscono già, e mettere la transazione in sospeso.

POST /transfer/txn
{"source":"john's account", "destination":"bob's account", "amount":10}

{"id":"/transfer/txn/12345", "state":"pending", "source":...}

Una volta che si dispone di questa transazione, si possono commettere, qualcosa di simile a:

PUT /transfer/txn/12345
{"id":"/transfer/txn/12345", "state":"committed", ...}

{"id":"/transfer/txn/12345", "state":"committed", ...}

Nota che più mette non importa a questo punto;anche a OTTENERE il txn sarebbe tornato allo stato attuale.In particolare, la seconda METTERE vorresti rilevare che il primo era già stato corretto, e basta tornare-o, se si tenta di mettere il "rolledback" stato, dopo che è già "impegnato" di stato, si dovrebbe ottenere un messaggio di errore e l'effettiva transazione indietro.

Fintanto che si parla di un singolo database, o di un database con un sistema integrato di controllo di transazione, questo meccanismo in realtà funziona proprio bene.Si potrebbe inoltre introdurre time-out per le operazioni, che si può esprimere anche utilizzando Scade intestazioni, se si voleva.

Nel RESTO termini, le risorse sono sostantivi che possono essere gestiti con CRUD (create/leggere/update/delete) verbi.Dal momento che non c'è "trasferimento soldi" verbo, abbiamo bisogno di definire una "transazione" di risorse che può essere azionata con il CRUD.Ecco un esempio in HTTP+POX.Il primo passo è quello di CREARE (Metodo HTTP POST) un nuovo vuoto transazione:

POST /transaction

Questo restituisce l'ID della transazione, ad esempio"1234" e secondo URL "/transazione/1234".Nota che la cottura questo POST più volte non crea la stessa operazione con più Id e evita anche l'introduzione di un "in sospeso".Inoltre i POST, non sempre può essere idempotente (un RESTO requisito), quindi è generalmente buona pratica per ridurre al minimo i dati in Post.

Si potrebbe lasciare la generazione di un ID di transazione con il cliente.In questo caso, si sarebbe posto /transazione/1234 per creare transazione "1234" e il server restituisce un errore se esisteva già.Nella risposta di errore, il server potrebbe tornare attualmente inutilizzati ID con un URL appropriato.Non è una buona idea per interrogare il server per un nuovo ID con un metodo GET, dal momento che OTTENERE non dovrebbe mai alterare lo stato del server e per la creazione e riservando un nuovo ID alterano lo stato del server.

Next up, abbiamo AGGIORNAMENTO (METTERE il metodo HTTP) l'operazione con tutti i dati, implicitamente, di impegnarsi:

PUT /transaction/1234
<transaction>
  <from>/account/john</from>
  <to>/account/bob</to>
  <amount>100</amount>
</transaction>

Se una transazione con ID "1234" è stato MESSO prima, il server fornisce una risposta di errore, altrimenti una risposta OK e un URL per visualizzare la transazione completata.

NB:in /account/giovanni "john" in realtà dovrebbe essere Giovanni numero del conto unico.

Grande domanda, il RESTO è in gran parte spiegato con database-come esempi, in cui qualcosa è memorizzato, aggiornati, recuperati, eliminato.Ci sono pochi esempi come questo, dove il server è supposto per elaborare i dati in qualche modo.Non credo che Roy Fielding incluso nella sua tesi, che era basato su http, dopo tutto.

Ma lui parla di "representational state transfer" come una macchina a stati, con collegamenti in movimento per il prossimo stato.In questo modo i documenti (le rappresentazioni) tenere traccia dei client di stato, anziché il server di doverlo fare.In questo modo, non c'è lo stato del client, solo in termini di link su cui si trovano.

Ho pensato a questo, e mi sembra ragionevole che per ottenere il server per elaborare qualcosa per voi, quando si carica, il server crea automaticamente le relative risorse, e dare il link (in realtà, non avrebbe bisogno di creare automaticamente di loro:si può solo dire il link, e si crea solo quando e se li segui pigro creazione).E per dare anche i link per creare nuovo risorse correlate - di una risorsa è lo stesso URI, ma è più lunga (aggiunge un suffisso).Per esempio:

  1. Si carica (POST) la rappresentazione del concetto di transazione con tutte le informazioni. Questa sembra proprio una chiamata RPC, ma è davvero creare la "proposta di transazione di risorse".e.g URI: /transaction Difetti causerà più risorse per essere creati, ognuno con un diverso URI.
  2. La risposta del server stati creati risorsa URI, la sua rappresentazione - questo include il collegamento (URI) per creare le relative risorse di un nuovo "transazione di risorse". Altre risorse sono i link per cancellare la transazione proposta.Questi sono stati nello stato-macchina, che il cliente può seguire.Logicamente, queste sono una parte delle risorse che è stato creato sul server, oltre che le informazioni che il client fornito.e.g Uri: /transaction/1234/proposed, /transaction/1234/committed
  3. Si POST al link creare la "transazione risorsa", che crea la risorsa, di modificare lo stato del server (i saldi dei due conti)**.Per sua natura, questa risorsa può essere creato solo una volta, e non possono essere aggiornati.Pertanto, glitch impegnare molte operazioni non può verificarsi.
  4. È possibile OTTENERE queste due risorse, per vedere che cosa il loro stato.Supponendo che un POST può modificare altre risorse, la proposta sarebbe ora essere contrassegnato come "impegnato" (o forse, non disponibile a tutti).

Questo è simile a come le pagine web di operare, con la finale della pagina web dicendo "sei sicuro di volerlo fare?" Che finale pagina web è di per sé una rappresentazione dello stato della transazione, che include un link per passare allo stato successivo.Non solo le transazioni finanziarie;anche (ad esempio) anteprima quindi eseguire il commit su wikipedia.Credo che la distinzione RESTO è che ogni fase della sequenza di stati ha un nome specifico (URI).

Nella vita reale le transazioni di vendita, ci sono spesso diversi documenti fisici per le diverse fasi di una transazione proposta, ordine di acquisto, ricevimento, ecc).Ancora di più per l'acquisto di una casa, con regolamento etc.

OTOH Questo si sente come giocare con la semantica per me;Mi sento a disagio con il nominalization di convertire i verbi in sostantivi per rendere Riposante, "perché utilizza i sostantivi (Uri) invece di verbi (chiamate RPC)".cioèil sostantivo "transazione risorsa" al posto del verbo "commettere questa operazione".Credo che uno dei vantaggi di nominalization è che si può fare riferimento alla risorsa per nome, invece di dover specificare in altro modo (ad esempio il mantenimento dello stato di sessione, in modo da sapere ciò che "questa" transazione...)

Ma la domanda importante è:Quali sono i vantaggi di questo approccio?cioèIn che modo è questo di tipo REST meglio di RPC-style?È una tecnica che è grande per le pagine web utili per l'elaborazione delle informazioni, al di là di archiviare e recuperare/update/delete?Penso che il vantaggio chiave del RESTO è la scalabilità;un aspetto di non dover mantenere lo stato del client in modo esplicito (ma che rende implicita l'URI della risorsa, e i prossimi stati come link nella sua rappresentazione).In che senso non aiuta.Forse questo aiuta a stratificazione/pipelining troppo?OTOH solo l'utente a guardare la loro specifica transazione, quindi non c'è nessun vantaggio in cache in modo che altri possono leggere, la grande vittoria per l'http.

Se vi levate in piedi indietro per riassumere la discussione qui, è abbastanza chiaro che il RESTO non è appropriato per molte Api, in particolare quando l'interazione client-server è intrinsecamente stateful, come non banali operazioni.Perché passare attraverso tutti i cerchi suggerito, per client e server, sia per pedissequamente seguire un principio che non si adattano al problema?Meglio il principio è quello di dare al cliente il modo più semplice, più naturale e produttiva modo di comporre con l'applicazione.

In sintesi, se si sta facendo un sacco di operazioni (tipo, non istanze) nell'applicazione, davvero non dovrebbe essere la creazione di una API RESTful.

Dovresti roll your own "id transazione" tipo di tx di gestione.Quindi sarebbe 4 chiamate:

http://service/transaction (some sort of tx request)
http://service/bankaccount/bob (give tx id)
http://service/bankaccount/john (give tx id)
http://service/transaction (request to commit)

Devi gestire la memorizzazione delle azioni in un DB (se il carico equilibrato) o nella memoria o come trattamento di commit, rollback, di timeout.

Non è davvero un giorno di riposo nel parco.

Ho allontanato da questo argomento per 10 anni.Tornare, non posso credere che la religione mascherata da scienza che wade quando si google resto+affidabile.La confusione è mitica.

Vorrei dividere questa vasta domanda in tre:

  • Servizi a valle.Qualsiasi servizio web che si sviluppano avrà a valle di servizi che si utilizza, e la cui transazione sintassi non hai scelta, ma per seguire.Si deve cercare di nascondere tutto questo da agli utenti del servizio, e assicurarsi che tutte le parti dell'operazione, successo o il fallimento come un gruppo, per poi tornare a questo risultato per i tuoi utenti.
  • I vostri servizi.I clienti vogliono inequivocabile risultati per web-chiamate di servizio, e il solito modello di RIPOSO di fare POST, PUT o ELIMINARE direttamente le richieste di sostanziale risorse mi colpisce come un povero, e facilmente migliorata, in modo di fornire a questa certezza.Se ti interessa l'affidabilità, è necessario identificare la richiesta di azione.Questo id può essere un guid creata sul client, o un valore di inizializzazione da un DB relazionale sul server, non importa.Per il server ha generato un ID, una richiesta di risposta è dedicato allo scambio di id.Se la richiesta ha esito negativo o la metà di esito positivo, nessun problema, il client si ripete solo la richiesta.Inutilizzati id "do no harm".

    Questo è importante perché consente a tutte le richieste successive a essere completamente idempotente, nel senso che se sono ripetute n volte ritornano lo stesso risultato e la causa più nulla accada.Il server memorizza tutte le risposte contro l'azione id, e se si vede la stessa richiesta, si ripete la stessa risposta.Una fuller trattamento del pattern è in questo google doc.Il doc suggerisce un'implementazione che, credo(!), ricalca RESTO entità.Gli esperti sarà sicuramente dimmi come è viola altri.Questo modello può essere utilmente impiegato per qualsiasi chiamata non sicura per il vostro web-servizio, anche se non ci sono a valle di operazioni coinvolte.
  • Integrazione del servizio in "operazioni" controllato da monte di servizi.Nel contesto del web-services, piena di ACIDO transazioni sono considerati come di solito non vale la pena, ma si può notevolmente aiutare i consumatori del servizio, fornendo annullare e/o di confermare il link nella mail di conferma di risposta, e quindi di ottenere le operazioni di compensazione.

Il requisito è fondamentale.Non permettere alle persone di dire la tua soluzione non è kosher.Giudicare le loro architetture, alla luce di quanto, e come, semplicemente, che a risolvere il problema.

Prima di tutto, il trasferimento di denaro è niente che non si possa fare in una singola risorsa chiamata.L'azione che si vuole fare è l'invio di denaro.Così si aggiunge un trasferimento di denaro, di risorse per conto del mittente.

POST: accounts/alice, new Transfer {target:"BOB", abmount:100, currency:"CHF"}.

Fatto.Non hai bisogno di sapere che questa è una operazione che deve essere atomica etc.Appena il trasferimento di denaro aka.inviare denaro da a a B.


Ma per i rari casi qui una soluzione generale:

Se si vuole fare qualcosa di molto complesso che coinvolge molte risorse in un contesto definito, con un sacco di restrizioni che attraversa realmente la cosa vs.perché barriera (azienda oconoscenza attuazione), è necessario trasferire stato.Dal momento che il RESTO dovrebbe essere stateless come cliente la necessità di trasferire lo stato intorno.

Se il trasferimento di stato è necessario nascondere le informazioni all'interno del client.Il cliente non deve sapere informazioni interne necessario solo per la realizzazione ma non trasportano le informazioni rilevanti in termini di business.Se tali informazioni non hanno valore di business per lo stato dovrebbero essere criptati e una metafora come token, pass o qualcosa di necessario per essere utilizzato.

In questo modo si può superare stato interno in giro e utilizzando la crittografia e la firma di un sistema può essere ancora sicuro e suono.Trovare il giusto astrazione per il cliente perché egli passa attorno informazioni di stato è qualcosa che è, al design e all'architettura.


La vera soluzione:

Ricordate RESTO sta parlando HTTP e HTTP viene fornito con il concetto di utilizzare i cookie.Tali cookie sono spesso dimenticati quando si parla di API REST e i flussi di lavoro e le interazioni che coinvolgono più risorse o richieste.

Ricordare ciò che è scritto in Wikipedia sui cookie HTTP:

I cookie sono stati progettati per essere un meccanismo affidabile per i siti web di ricordare stateful informazioni (come ad esempio gli articoli nel carrello) oppure per registrare l'utente, attività di navigazione (ad esempio cliccando particolare pulsanti, registrazione o la registrazione delle quali pagine sono state visitate dall'utente nel lontano mesi o anni fa).

Quindi, fondamentalmente, se avete bisogno di passare, utilizzare un cookie.È stato progettato esattamente per lo stesso motivo, è HTTP e quindi è compatibile con il RESTO del design :).


La soluzione migliore:

Se si parla di un client di eseguire un flusso di lavoro che coinvolgono molteplici richieste che di solito parlano di protocollo.Ogni forma di protocollo viene fornito con una serie di precondizioni per ogni potenziale passo come eseguire il passaggio di Una prima, si può fare B.

Questo è naturale, ma di esporre il protocollo client rende tutto più complesso.Per evitarlo basta pensare a ciò che facciamo quando abbiamo a che fare complesse interazioni e le cose nel mondo reale....Usiamo un Agente.

L'Agente metafora è in grado di fornire una risorsa in grado di eseguire tutti i passi necessari per voi e memorizzare l'effettiva assegnazione / istruzioni di agire su nella sua lista (in modo da poter usare il POST sull'agente o un 'agenzia').

Un esempio complesso:

L'acquisto di una casa:

È necessario dimostrare la vostra credibilità (come quello di fornire la vostra polizia voci di record), è necessario verificare i dettagli finanziari, è necessario acquistare la casa vera e propria utilizzando un avvocato e un terzo di fiducia memorizzazione di fondi, di verificare che la casa appartiene a voi e aggiungere l'acquisto di materiale per i vostri documenti fiscali etc.(solo per fare un esempio, alcuni passaggi possono essere sbagliate o qualsiasi altra cosa).

Questi passaggi possono richiedere diversi giorni per essere completato, alcuni possono essere eseguiti in parallelo, etc.

Per fare questo, è sufficiente dare l'agente il compito di acquistare casa, come:

POST: agency.com/ { task: "buy house", target:"link:toHouse", credibilities:"IamMe"}.

Fatto.L'agenzia restituisce un riferimento a voi che è possibile utilizzare per visualizzare e controllare lo stato di questo lavoro e il resto viene fatto automaticamente da parte di agenti dell'agenzia.

Pensare a un bug tracker per esempio.Fondamentalmente si segnala il bug e possibile utilizzare il bug id per controllare cosa sta succedendo.È anche possibile utilizzare un servizio per l'ascolto di modifiche di questa risorsa.Missione Fatto.

Penso che in questo caso è del tutto accettabile per rompere la teoria pura del RESTO in questa situazione.In ogni caso, non credo che ci sia qualcosa di effettivamente nel RESTO che dice che non si può toccare gli oggetti dipendenti nei casi che lo richiedono.

Penso proprio che non vale la pena extra hoops si dovrebbe passare attraverso di creare un custom di gestione delle transazioni, quando si potrebbe sfruttare il database di farlo.

Non si deve utilizzare il lato server transazioni nel RESTO.

Fra il RESTO vincoli:

Stateless

La comunicazione client–server è ulteriormente vincolata da nessun client contesto di essere memorizzati sul server tra le richieste.Ogni richiesta da qualsiasi client contiene tutte le informazioni necessarie per soddisfare la richiesta, e di ogni sessione, è stato tenuto nel client.

L'unica Riposante modo è quello di creare una transazione redo log e messo in stato di cliente.Con le richieste del client invia il log di ripristino e il server ripete l'operazione e

  1. rollback della transazione, ma fornisce una nuova transazione redo log (un passo avanti)
  2. o, infine, completare la transazione.

Ma forse è più semplice per utilizzare un server basato su sessioni tecnologia che supporta lato server transazioni.

Credo che sarebbe il caso di utilizzare un identificatore univoco generato sul client per assicurarsi che la connessione a singhiozzo non implica in una doppiezza salvato dall'API.

Penso che utilizzando un client GUID generato in campo insieme con l'oggetto di trasferimento e di garantire che lo stesso GUID non è stato reinserito di nuovo sarebbe una soluzione più semplice per il bonifico bancario materia.

Non so scenari più complessi, come ad esempio più di un biglietto di prenotazione o di micro architetture.

Ho trovato una carta sull'argomento, riguardanti le esperienze di trattare con l'atomicità delle transazioni in servizi RESTful.

Nel caso più semplice (senza risorse distribuite), si potrebbe considerare l'operazione come una risorsa, dove l'atto della creazione si raggiunge l'obiettivo finale.

Così, per il trasferimento tra <url-base>/account/a e <url-base>/account/b, si potrebbe postare il seguito di <url-base>/transfer.

<transfer>
    <from><url-base>/account/a</from>
    <to><url-base>/account/b</to>
    <amount>50</amount>
</transfer>

Questo permetterebbe di creare un nuovo trasferimento di risorse e di ritorno il nuovo url del trasferimento, ad esempio <url-base>/transfer/256.

Al momento di successo, quindi, la 'vera' operazione è effettuata sul server, e la quantità rimossa da un account e aggiunto a un altro.

Questo, tuttavia, non copre una transazione distribuita (se, per esempio 'a' è tenuto presso una banca dietro un servizio, e 'b' si svolge presso un'altra banca dietro l'altro di servizio) - di dire "provare per la frase tutte le operazioni in modi che non richiedono transazioni distribuite".

Credo che si potrebbe includere il TAN nell'URL/risorsa:

  1. METTERE /transazione per ottenere l'ID (es."1")
  2. [PUT, GET, POST, indipendentemente] /1/account/bob
  3. [PUT, GET, POST, indipendentemente] /1/account/bill
  4. ELIMINARE /transazione con ID 1

Solo un'idea.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top