Transazioni in REST?


147

Mi chiedo come implementeresti il ​​seguente caso d'uso in REST. È anche possibile fare a meno del modello concettuale?

Leggi o aggiorna più risorse nell'ambito di una singola transazione. Ad esempio, trasferisci $ 100 dal conto bancario di Bob al conto John.

Per quanto ne so, l'unico modo per implementarlo è imbrogliare. È possibile inviare alla risorsa associata a John o Bob ed eseguire l'intera operazione utilizzando una singola transazione. Per quanto mi riguarda, questo rompe l'architettura REST perché essenzialmente si esegue il tunneling di una chiamata RPC tramite POST invece di operare realmente su singole risorse.

Risposte:


91

Prendi in considerazione uno scenario RESTful del carrello. Il carrello è concettualmente il wrapper della transazione. Allo stesso modo in cui è possibile aggiungere più articoli a un carrello e quindi inviare quel carrello per elaborare l'ordine, è possibile aggiungere la voce del conto di Bob al wrapper della transazione e quindi la voce del conto di Bill al wrapper. Quando tutti i pezzi sono a posto, è possibile POST / PUT il wrapper di transazione con tutti i pezzi componenti.


18
Perché TransferMoneyTransaction non sarebbe una risorsa bancaria valida?
Darrel Miller,

8
Se ti assicuri che i tuoi endpoint si riferiscano a nomi allora di solito è intuitivo cosa faranno i verbi standard GET, PUT, POST, DELETE a quel nome. RPC consente agli endpoint di essere verbi stessi e pertanto possono entrare in conflitto con i verbi HTTP e l'intento diventa confuso.
Darrel Miller,

10
ad es. Cosa succede se si esegue una CANCELLAZIONE HTTP sull'endpoint UpdateXYZ? Elimina XYZ? Elimina l'aggiornamento o esegue semplicemente un aggiornamento e ignora l'eliminazione del verbo HTTP. Tenendo i verbi fuori dall'endpoint si rimuove la confusione.
Darrel Miller,

5
E le transazioni tra più servizi? e che dire di quando si desidera apportare una serie di modifiche "non correlate" che il servizio non espone alcun contenitore di transazioni implicite. Inoltre, perché avere un tipo di transazione specifico quando ci spostiamo in transazioni di uso generale completamente non correlate ai dati effettivi i cambiamenti. Le transazioni potrebbero non corrispondere a quelle riposanti, ma sembra che le transazioni debbano essere sovrapposte, non correlate alle altre chiamate, a parte il fatto che le intestazioni della richiesta conterrebbero un riferimento alla transazione.
meandmycode,

4
@meandmycode Le transazioni del database devono essere stratificate dietro un'interfaccia REST. In alternativa è possibile esporre una transazione commerciale (non una transazione di database) come risorsa in sé e quindi è necessario intraprendere azioni compensative in caso di fallimento.
Darrel Miller,

60

Ci sono alcuni casi importanti a cui non viene data risposta da questa domanda, che ritengo sia troppo grave, perché ha un alto posizionamento su Google per i termini di ricerca :-)

In particolare, sarebbe una buona cosa: se POST due volte (perché un po 'di cache ha avuto un singhiozzo nell'intermedio) non dovresti trasferire l'importo due volte.

Per arrivare a questo, si crea una transazione come oggetto. Questo potrebbe contenere tutti i dati che già conosci e mettere la transazione in uno stato 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 hai questa transazione, puoi impegnarla, qualcosa del tipo:

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

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

Si noti che più put non contano a questo punto; anche un GET sul txn restituirebbe lo stato corrente. In particolare, il secondo PUT rileverà che il primo era già nello stato appropriato e lo restituirebbe semplicemente, oppure, se si tenta di metterlo nello stato "rollback" dopo che è già nello stato "impegnato", si otterrebbe uno errore e la transazione effettivamente impegnata indietro.

Finché si parla con un singolo database o un database con un monitor integrato delle transazioni, questo meccanismo funzionerà davvero bene. Potresti inoltre introdurre timeout per le transazioni, che potresti anche esprimere usando le intestazioni di Scadenza se lo desideri.


Discussione interessante! Vorrei aggiungere che il post iniziale deve essere eseguito in un solo passaggio. Non può essere aggiunto in un secondo momento (quindi siamo nel territorio del carrello della spesa e i carrelli della spesa hanno molti controlli e saldi per impedire loro di causare danni all'utente finale, anche la legislazione, i bonifici non lo fanno) ...
Erk

33

In termini REST, le risorse sono nomi su cui si può agire con i verbi CRUD (creare / leggere / aggiornare / cancellare). Poiché non esiste un verbo "trasferire denaro", è necessario definire una risorsa "transazione" su cui si possa agire con CRUD. Ecco un esempio in HTTP + POX. Il primo passo è CREARE (metodo HTTP POST) una nuova transazione vuota :

POST /transaction

Ciò restituisce un ID transazione, ad es. "1234" e secondo l'URL "/ transazione / 1234". Si noti che l'attivazione di questo POST più volte non creerà la stessa transazione con più ID ed evita inoltre l'introduzione di uno stato "in sospeso". Inoltre, il POST non può sempre essere idempotente (un requisito REST), quindi è generalmente buona pratica ridurre al minimo i dati nei POST.

È possibile lasciare la generazione di un ID transazione al cliente. In questo caso, si dovrebbe POST / transazione / 1234 per creare la transazione "1234" e il server restituirebbe un errore se esistesse già. Nella risposta all'errore, il server potrebbe restituire un ID attualmente inutilizzato con un URL appropriato. Non è una buona idea richiedere al server un nuovo ID con un metodo GET, poiché GET non dovrebbe mai alterare lo stato del server e la creazione / prenotazione di un nuovo ID altererebbe lo stato del server.

Successivamente, AGGIORNIAMO (metodo PUT HTTP) la transazione con tutti i dati, commettendola implicitamente:

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

Se in precedenza è stata inserita una transazione con ID "1234", il server fornisce una risposta di errore, altrimenti una risposta OK e un URL per visualizzare la transazione completata.

NB: in / account / john, "john" dovrebbe davvero essere il numero di account univoco di John.


4
Associare REST a CRUD è un grave errore. POST non deve significare CREATE.

12
Grave errore? So che ci sono differenze tra PUT e POST, ma esiste una mappatura libera su CRUD. "Sul serio"?
Ted Johnson,

3
Si, seriamente. CRUD è un modo di strutturare l'archiviazione dei dati; REST è un modo di strutturare il flusso di dati dell'applicazione. È possibile eseguire CRUD su REST, ma non è possibile eseguire REST su CRUD. Non sono equivalenti.
Jon Watte,

20

Ottima domanda, REST viene principalmente spiegato con esempi simili a database, in cui qualcosa viene archiviato, aggiornato, recuperato, eliminato. Ci sono alcuni esempi come questo, in cui il server dovrebbe elaborare i dati in qualche modo. Non credo che Roy Fielding ne abbia incluso nessuno nella sua tesi, che dopo tutto si basava su http.

Ma parla di "trasferimento rappresentativo dello stato" come una macchina a stati, con collegamenti che si spostano allo stato successivo. In questo modo, i documenti (le rappresentazioni) tengono traccia dello stato del client, invece che il server debba farlo. In questo modo, non esiste uno stato client, solo lo stato in termini di quale collegamento si trova.

Ci ho pensato, e mi sembra ragionevole che per far sì che il server elabori qualcosa per te, quando carichi, il server creerebbe automaticamente risorse correlate e ti fornirà i collegamenti (in realtà, non non è necessario crearli automaticamente: potrebbe semplicemente dirti i collegamenti e li creerà solo quando e se li segui - creazione pigra). E per fornire anche collegamenti per creare nuove risorse correlate: una risorsa correlata ha lo stesso URI ma è più lunga (aggiunge un suffisso). Per esempio:

  1. Carichi ( POST ) la rappresentazione del concetto di transazione con tutte le informazioni. Sembra proprio una chiamata RPC, ma sta davvero creando la "risorsa di transazione proposta". ad es. URI: i /transaction glitch causeranno la creazione di più di tali risorse, ognuna con un URI diverso.
  2. La risposta del server indica l'URI della risorsa creata, la sua rappresentazione - questo include il collegamento ( URI ) per creare la risorsa correlata di una nuova "risorsa di transazione impegnata". Altre risorse correlate sono il link per eliminare la transazione proposta. Questi sono stati nella macchina a stati, che il client può seguire. Logicamente, fanno parte della risorsa che è stata creata sul server, oltre alle informazioni fornite dal client. es URI: /transaction/1234/proposed, /transaction/1234/committed
  3. Si POST al link per creare la "risorsa di transazione impegnato" , che crea quella risorsa, cambiare lo stato del server (i saldi delle due conti) **. Per sua natura, questa risorsa può essere creata una sola volta e non può essere aggiornata. Pertanto, i glitch che commettono molte transazioni non possono verificarsi.
  4. Puoi OTTENERE quelle due risorse per vedere qual è il loro stato. Supponendo che un POST possa modificare altre risorse, la proposta verrebbe ora contrassegnata come "impegnata" (o forse non disponibile affatto).

Questo è simile a come funzionano le pagine web, con la pagina finale che dice "sei sicuro di voler fare questo?" Quella pagina web finale è essa stessa una rappresentazione dello stato della transazione, che include un collegamento per passare allo stato successivo. Non solo transazioni finanziarie; anche (ad esempio) l'anteprima, quindi esegui il commit su wikipedia. Immagino che la distinzione in REST sia che ogni fase della sequenza di stati ha un nome esplicito (il suo URI).

Nelle transazioni / vendite nella vita reale, ci sono spesso documenti fisici diversi per le diverse fasi di una transazione (proposta, ordine di acquisto, ricevuta ecc.). Ancora di più per l'acquisto di una casa, con insediamento ecc.

OTOH Mi sembra di giocare con la semantica; Non mi sento a mio agio con la nominalizzazione della conversione dei verbi in sostantivi per renderlo RESTful, "perché usa nomi (URI) anziché verbi (chiamate RPC)". vale a dire il nome "risorsa transazione impegnata" invece del verbo "commettere questa transazione". Immagino che un vantaggio della nominalizzazione sia che puoi fare riferimento alla risorsa per nome, invece di doverlo specificare in qualche altro modo (come mantenere lo stato della sessione, quindi sai cos'è "questa" transazione ...)

Ma la domanda importante è: quali sono i vantaggi di questo approccio? cioè In che modo questo stile REST è migliore di quello RPC? Una tecnica eccezionale per le pagine Web è utile anche per l'elaborazione delle informazioni, oltre a memorizzare / recuperare / aggiornare / eliminare? Penso che il vantaggio principale di REST sia la scalabilità; un aspetto di questo non è necessario per mantenere esplicitamente lo stato del client (ma rendendolo implicito nell'URI della risorsa, e gli stati successivi come collegamenti nella sua rappresentazione). In questo senso aiuta. Forse questo aiuta anche nella stratificazione / pipeline? OTOH solo un utente guarderà la propria transazione specifica, quindi non c'è alcun vantaggio nella memorizzazione nella cache in modo che altri possano leggerlo, la grande vittoria per http.


Potresti spiegare in che modo "non aver bisogno di mantenere lo stato sul client" aiuta la scalabilità? Che tipo di scalabilità? Scalabilità in che senso?
jhegedus,

11

Se torni indietro a riassumere la discussione qui, è abbastanza chiaro che REST non è appropriato per molte API, in particolare quando l'interazione client-server è intrinsecamente con stato, come lo è con transazioni non banali. Perché saltare attraverso tutti i cerchi suggeriti, sia per client che per server, al fine di seguire pedanticamente alcuni principi che non si adattano al problema? Un principio migliore è quello di fornire al cliente il modo più semplice, più naturale e produttivo per comporre l'applicazione.

In sintesi, se stai davvero facendo molte transazioni (tipi, non istanze) nella tua applicazione, non dovresti davvero creare un'API RESTful.


9
Giusto, ma quale dovrebbe essere un'alternativa in caso di architettura di micro-servizi distribuiti?
Vitamon,

11

Mi sono allontanato da questo argomento per 10 anni. Tornando, non riesco a credere alla religione mascherata da scienza in cui ti guadagni quando vai su Google + affidabile. La confusione è mitica.

Dividerei questa ampia domanda in tre:

  • Servizi a valle. Qualsiasi servizio web che svilupperai avrà servizi a valle che utilizzi e la cui sintassi delle transazioni non hai altra scelta che seguire. Dovresti provare a nascondere tutto ciò agli utenti del tuo servizio e assicurarti che tutte le parti dell'operazione abbiano successo o meno come gruppo, quindi restituisci questo risultato ai tuoi utenti.
  • I tuoi servizi I clienti desiderano risultati inequivocabili per le chiamate al servizio Web e il solito modello REST di invio di richieste POST, PUT o DELETE direttamente su risorse sostanziali mi sembra un modo scadente e facilmente migliorato di fornire questa certezza. Se ti preoccupi dell'affidabilità, devi identificare le richieste di intervento. Questo ID può essere una guida creata sul client o un valore seed da un DB relazionale sul server, non importa. Per gli ID generati dal server, utilizzare una richiesta-risposta "verifica preliminare" per scambiare l'id dell'azione. Se questa richiesta ha esito negativo o metà ha esito positivo, nessun problema, il client ripete semplicemente la richiesta. Gli ID non utilizzati non danneggiano.

    Questo è importante perché consente a tutte le richieste successive di essere completamente idempotenti, nel senso che se vengono ripetute n volte restituiscono lo stesso risultato e non fanno accadere altro. Il server memorizza tutte le risposte sull'ID azione e, se vede la stessa richiesta, riproduce la stessa risposta. Un trattamento più completo del modello è in questo documento di Google . Il documento suggerisce un'implementazione che, credo (!), Segue ampiamente i principi REST. Gli esperti sicuramente mi diranno come viola gli altri. Questo modello può essere utilmente utilizzato per qualsiasi chiamata non sicura al tuo servizio web, indipendentemente dal fatto che siano coinvolte o meno transazioni a valle.
  • Integrazione del servizio in "transazioni" controllate da servizi a monte. Nel contesto dei servizi Web, le transazioni ACID complete sono considerate di solito non meritevoli di sforzo, ma puoi aiutare notevolmente i consumatori del tuo servizio fornendo collegamenti di annullamento e / o conferma nella risposta di conferma, e quindi ottenere transazioni mediante compensazione .

Il tuo requisito è fondamentale. Non lasciare che la gente ti dica che la tua soluzione non è kosher. Giudica le loro architetture alla luce di quanto bene e quanto semplicemente affrontano il tuo problema.


9

Dovresti creare il tuo tipo "ID transazione" di gestione tx. Quindi sarebbero 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)

Dovresti gestire la memorizzazione delle azioni in un DB (se il carico è bilanciato) o in memoria o simili, quindi gestire il commit, il rollback, il timeout.

Non proprio una giornata RESTful nel parco.


4
Non penso che questa sia un'illustrazione particolarmente valida. Sono necessari solo due passaggi: Crea transazione (crea una transazione nello stato "in sospeso") e Commetti transazione (esegue il commit se non è stato eseguito il commit e sposta la risorsa nello stato di commit o rollback).
Jon Watte,

2

Penso che in questo caso sia assolutamente accettabile infrangere la pura teoria del REST in questa situazione. In ogni caso, non credo che ci sia qualcosa in realtà in REST che dica che non è possibile toccare oggetti dipendenti in casi aziendali che lo richiedono.

Penso davvero che non valga la pena spendere di più per creare un gestore delle transazioni personalizzato, quando potresti semplicemente sfruttare il database per farlo.


2

Innanzitutto il trasferimento di denaro non è cosa che non puoi fare in una singola chiamata di risorse. L'azione che vuoi fare è inviare denaro. Quindi aggiungi una risorsa di trasferimento di denaro all'account del mittente.

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

Fatto. Non è necessario sapere che si tratta di una transazione che deve essere atomica, ecc. È sufficiente trasferire denaro alias. inviare denaro da A a B.


Ma per i rari casi qui una soluzione generale:

Se vuoi fare qualcosa di molto complesso che coinvolge molte risorse in un contesto definito con molte restrizioni che attraversano effettivamente la barriera what vs. why (conoscenza aziendale vs. implementazione) devi trasferire lo stato. Poiché REST dovrebbe essere apolide, come client è necessario trasferire lo stato in giro.

Se si trasferisce lo stato, è necessario nascondere le informazioni all'interno dal client. Il cliente non dovrebbe conoscere le informazioni interne necessarie solo per l'implementazione, ma non deve contenere informazioni rilevanti in termini di business. Se tali informazioni non hanno valore commerciale, lo stato deve essere crittografato e deve essere utilizzata una metafora come token, pass o altro.

In questo modo si può passare lo stato interno e usare la crittografia e firmare il sistema può essere ancora sicuro e solido. Trovare l'astrazione giusta per il cliente per cui passa informazioni sullo stato è qualcosa che dipende dal design e dall'architettura.


La vera soluzione:

Ricorda che REST sta parlando HTTP e HTTP viene fornito con il concetto di utilizzo dei cookie. Questi cookie vengono spesso dimenticati quando le persone parlano dell'API REST e dei flussi di lavoro e delle interazioni che coprono più risorse o richieste.

Ricorda cosa è scritto in Wikipedia sui cookie HTTP:

I cookie sono stati progettati per essere un meccanismo affidabile per i siti Web per ricordare informazioni statali (come gli articoli in un carrello della spesa) o per registrare l'attività di navigazione dell'utente (inclusi clic su pulsanti particolari, accesso o registrazione delle pagine visitate dall'utente fino a quel momento) come mesi o anni fa).

Quindi, in pratica, se è necessario trasmettere lo stato, utilizzare un cookie. È progettato esattamente per lo stesso motivo, è HTTP e quindi è compatibile con REST di progettazione :).


La soluzione migliore:

Se parli di un client che esegue un flusso di lavoro che coinvolge più richieste, di solito parli di protocollo. Ogni forma di protocollo viene fornita con una serie di precondizioni per ogni potenziale passaggio come eseguire il passaggio A prima di poter eseguire B.

Questo è naturale ma esporre il protocollo ai client rende tutto più complesso. Per evitarlo, pensa solo a ciò che facciamo quando dobbiamo fare interazioni e cose complesse nel mondo reale .... Usiamo un agente.

Usando la metafora dell'Agente puoi fornire una risorsa in grado di eseguire tutti i passaggi necessari per te e archiviare l'assegnazione / le istruzioni effettive su cui sta agendo nel suo elenco (in modo che possiamo usare POST sull'agente o su un'agenzia).

Un esempio complesso:

Comprare una casa:

Devi dimostrare la tua credibilità (come fornire le voci del tuo registro di polizia), devi assicurarti i dettagli finanziari, devi comprare la casa reale usando un avvocato e un terzo fidato che immagazzina i fondi, verificare che la casa ora appartiene a te e aggiungi gli articoli acquistati ai tuoi registri fiscali ecc. (solo come esempio, alcuni passaggi potrebbero essere errati o altro).

Il completamento di questi passaggi potrebbe richiedere alcuni giorni, alcuni in parallelo, ecc.

Per fare questo, devi solo dare all'agente il compito di comprare casa come:

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

Fatto. L'agenzia ti restituisce un riferimento che puoi utilizzare per vedere e tracciare lo stato di questo lavoro e il resto viene fatto automaticamente dagli agenti dell'agenzia.

Pensa ad un bug tracker per esempio. Fondamentalmente si segnala il bug e si può usare l'id del bug per verificare cosa sta succedendo. Puoi persino usare un servizio per ascoltare i cambiamenti di questa risorsa. Missione completata.


1

Non è necessario utilizzare le transazioni lato server in REST.

Una delle contraffazioni REST:

apolide

La comunicazione client-server è ulteriormente limitata dal fatto che nessun contesto client viene memorizzato sul server tra le richieste. Ogni richiesta da qualsiasi client contiene tutte le informazioni necessarie per soddisfare la richiesta e ogni stato di sessione viene mantenuto nel client.

L'unico modo RESTful è creare un registro di ripetizione della transazione e metterlo nello stato client. Con le richieste il client invia il registro di ripetizione e il server ripristina la transazione e

  1. ripristina la transazione ma fornisce un nuovo registro di ripetizione della transazione (un ulteriore passo avanti)
  2. o infine completa la transazione.

Ma forse è più semplice utilizzare una tecnologia basata su sessione server che supporti le transazioni lato server.


La citazione proviene dalla voce REST di Wikipedia. È questa la vera fonte o Wikipedia l'ha preso da qualche parte? Chi può dire qual è il contesto client e qual è il contesto server?
bbsimonbb,

1

Credo che sarebbe il caso di utilizzare un identificatore univoco generato sul client per garantire che il singhiozzo della connessione non implichi una duplicità salvata dall'API.

Penso che l'utilizzo di un campo GUID generato dal client insieme all'oggetto di trasferimento e la garanzia che lo stesso GUID non sia stato reinserito di nuovo sarebbe una soluzione più semplice alla questione del trasferimento bancario.

Non conoscere scenari più complessi, come la prenotazione di biglietti aerei multipli o microarchitettura.

Ho trovato un documento sull'argomento, relativo alle esperienze di gestione dell'atomicità delle transazioni nei servizi RESTful .


0

Nel caso semplice (senza risorse distribuite), è possibile considerare la transazione come una risorsa, in cui l'atto di crearla raggiunge l'obiettivo finale.

Quindi, per trasferire tra <url-base>/account/ae <url-base>/account/b, è possibile pubblicare quanto segue <url-base>/transfer.

<Trasferimento>
    <Da> <url-base> / account / a </ da>
    <A> <url-base> / account / b </ a>
    <Quantità> 50 </ importo>
</ Trasferimento>

Ciò creerebbe una nuova risorsa di trasferimento e restituire il nuovo URL del trasferimento, ad esempio <url-base>/transfer/256.

Al momento della pubblicazione corretta, quindi, la transazione "reale" viene eseguita sul server e l'importo rimosso da un account e aggiunto a un altro.

Questo, tuttavia, non copre una transazione distribuita (se, per esempio, 'a' è detenuto in una banca dietro un servizio, e 'b' è detenuto in un'altra banca dietro un altro servizio) - a parte dire "prova a pronunciare tutto operazioni in modi che non richiedono transazioni distribuite ".


2
Se non riesci a "pronunciare tutte le operazioni in modi che non richiedono transazioni distribuite", hai davvero bisogno di un commit in due fasi. L'idea migliore che ho trovato per l'implementazione di un commit a due fasi su REST è rest.blueoxen.net/cgi-bin/wiki.pl?TwoPhaseCommit , che importante non rovina lo spazio dei nomi URL e consente di sovrapporre un commit a due fasi semantica REST pulita.
Phasmal,

3
L'altro problema con questo suggerimento è che, se un singhiozzo della cache e POST due volte, si ottengono due trasferimenti.
Jon Watte,

È vero, nel qual caso avresti bisogno di un processo in due passaggi: crea una risorsa di "trasferimento" con un URL univoco, quindi aggiungi i dettagli del trasferimento come parte del commit (due parti come menzionato nelle altre risposte). Naturalmente, questo potrebbe quindi essere definito come creazione di una risorsa "transazione" e aggiunta di un'operazione di "trasferimento".
Phasmal

-3

Immagino che potresti includere la TAN nell'URL / risorsa:

  1. PUT / transazione per ottenere l'ID (ad es. "1")
  2. [PUT, GET, POST, qualunque cosa] / 1 / account / bob
  3. [PUT, GET, POST, qualunque cosa] / 1 / account / fattura
  4. ELIMINA / transazione con ID 1

Solo un'idea


Vedo due problemi con questo approccio: 1) Implica che non puoi accedere a una risorsa al di fuori di una transazione (anche se forse questo non è un grosso problema). 2) Nessuna delle risposte finora ha toccato il fatto che il server non è più apolide, anche se sospetto che non si possa fare nulla al riguardo.
Gili,

Bene, / 1 / account / bob e / account / bob sono solo due risorse diverse. :) E RE: senza stato, implica che la risorsa è sempre disponibile e non dipende da una richiesta precedente. Dato che hai chiesto le transazioni, sì, non è così. Ma poi di nuovo, volevi transazioni.
Fino al

1
Se un client deve assemblare URI, l'API non è RESTful.
aehlke,

1
Ragazzi, non capisco davvero! Se trattate una transazione come una risorsa (come nell'esempio sopra) semplicemente smettete di trattare la transazione in senso classico e la utilizzate in "modo REST corretto" che semplifica ulteriormente la programmazione dei processi transazionali. Ad esempio, puoi includere un href alla transazione nelle tue risposte per aggirare lo spostamento nell'ambiente distribuito sul lato server, è ancora apolide (è solo una risorsa, non è vero?) E puoi comunque implementare il meccanismo di transazione vero e proprio vuoi (cosa succede se non hai un DB nella parte posteriore?)
Matthias Hryniszak,

1
In un modo o nell'altro se smetti semplicemente di pensare a SQL / SOAP e inizi a pensare a HTTP (come fa il browser) tutto diventa semplice
Matthias Hryniszak,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.