Операції в REST?


147

Мені цікаво, як би ви реалізували наступний випадок використання в REST. Чи можливо навіть обійтися без шкоди для концептуальної моделі?

Читання або оновлення декількох ресурсів у межах однієї транзакції. Наприклад, перерахуйте 100 доларів з банківського рахунку Боба на рахунок Джона.

Наскільки я можу сказати, єдиний спосіб здійснити це шляхом обману. Ви можете POST на ресурс, пов’язаний або з Джоном, або з Боб, і здійснити всю операцію, використовуючи одну транзакцію. Що стосується мене, це порушує архітектуру REST, тому що ви по суті налаштовуєте виклик RPC через POST, а не реально працюєте на окремих ресурсах.

Відповіді:


91

Розглянемо сценарій ВИПУСКОВОГО кошика. Кошик для покупок - це обгортка вашої транзакції. Таким чином, як ви можете додати кілька предметів до кошика для покупок, а потім подати кошик для обробки замовлення, ви можете додати запис облікового запису Боба до обгортки транзакцій, а потім ввести рахунок рахунку Білла в обгортку. Коли всі шматки є на місці, ви можете НАВІДКЛЮЧАТИ / ВІДКЛЮЧИТИ обгортку транзакцій з усіма компонентами.


18
Чому TransferMoneyTransaction не буде життєздатним банківським ресурсом?
Даррел Міллер

8
Якщо ви переконайтеся, що ваші кінцеві точки посилаються на іменники, то зазвичай інтуїтивно зрозуміло, що стандартні дієслова GET, PUT, POST, DELETE будуть робити з цим іменником. RPC дозволяє кінцевим точкам бути самими дієсловами, і тому вони можуть конфліктувати з HTTP-дієсловами, і намір стає заплутаним.
Даррел Міллер

10
Наприклад, що станеться, якщо ви зробите HTTP DELETE на кінцевій точці UpdateXYZ? Чи видаляє XYZ? Чи видаляє оновлення чи просто робить оновлення та ігнорує видалення дієслова HTTP. Утримуючи дієслова від кінцевої точки, ви усуваєте плутанину.
Даррел Міллер

5
А як щодо транзакцій у кількох сервісах? а що робити, коли ви хочете зробити набір "непов'язаних" змін, що служба не піддається неявному контейнеру транзакцій? зміни. Операції можуть не відповідати спокійним, але, схоже, транзакції повинні бути шаруватими на вершині, не пов'язаними з іншими дзвінками, крім того, що заголовки запитів міститимуть посилання на транзакцію.
meandmycode

4
@meandmycode Транзакції бази даних повинні бути шаруватими за інтерфейсом REST. Крім того, ви можете викрити бізнес-операції (а не транзакції з базою даних) як сам по собі ресурс, і тоді вам потрібно буде вжити компенсуючих заходів у разі відмови.
Даррел Міллер

60

Є кілька важливих випадків, на які не відповідає відповідь на це запитання, що я вважаю занадто поганим, оскільки він має високий рейтинг в Google за пошуковими термінами :-)

Зокрема, приємно було б: Якщо ви відправляєте POST двічі (оскільки якийсь кеш іконується в проміжному), ви не повинні переводити суму двічі.

Щоб дійти до цього, ви створюєте транзакцію як об’єкт. Це може містити всі відомості, які ви вже знаєте, і приводити транзакцію до стану очікування.

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

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

Щойно у вас є ця транзакція, ви можете її здійснити приблизно так:

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

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

Зверніть увагу, що на даний момент кілька значень не мають значення; навіть GET на txn поверне поточний стан. Зокрема, другий PUT виявить, що перший вже знаходиться у відповідному стані, і просто поверне його - або, якщо ви спробуєте перевести його у стан "відкат" після того, як він вже знаходиться у "скоєному" стані, ви отримаєте помилка та фактично здійснена транзакція.

Поки ви спілкуєтесь з однією базою даних або базою даних з інтегрованим монітором транзакцій, цей механізм насправді буде працювати чудово. Ви можете додатково ввести тайм-аути для транзакцій, які ви навіть можете виразити, використовуючи заголовки Expires, якщо хочете.


Цікава дискусія! Хочу додати, що початкову посаду потрібно виконувати за один крок. Його не можна додати пізніше (тоді ми знаходимось на території кошика, а у візків є багато чеків і противаг, щоб вони не завдали шкоди кінцевому користувачеві, навіть законодавство, банківські перекази не мають) ...
Ерк

33

У терміні REST ресурси - це іменники, на які можна діяти за допомогою дієслів CRUD (створення / читання / оновлення / видалення). Оскільки дієслова "переказувати гроші" немає, нам потрібно визначити "транзакційний" ресурс, з яким можна діяти за допомогою CRUD. Ось приклад у HTTP + POX. Перший крок - СТВОРИТИ (метод HTTP POST) нової порожньої транзакції:

POST /transaction

Це повертає ідентифікатор транзакції, наприклад, "1234" та відповідно до URL "/ транзакція / 1234". Зауважте, що запуск цього POST кілька разів не призведе до тієї самої транзакції з декількома ідентифікаторами, а також уникне введення "очікуваного" стану. Також POST не завжди може бути ідентичним (вимога REST), тому загалом є хорошою практикою мінімізувати дані в POST.

Ви можете залишити генерацію ідентифікатора транзакції клієнту. У цьому випадку ви POST / transakcija / 1234 створити транзакцію "1234", і сервер поверне помилку, якщо вона вже існувала. У відповіді на помилку сервер може повернути поточно використаний ідентифікатор з відповідною URL-адресою. Недоцільно запитувати сервер на новий ідентифікатор методом GET, оскільки GET ніколи не повинен змінювати стан сервера, а створення / резервування нового ідентифікатора змінило б стан сервера.

Далі ми ОНОВЛЮЄМО (метод PUT HTTP) транзакції з усіма даними, неявно здійснюючи їх:

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

Якщо транзакція з ідентифікатором "1234" раніше була PUT, сервер видає відповідь про помилку, інакше відповідь ОК і URL для перегляду завершеної транзакції.

Примітка: в / account / john, "john" дійсно повинен бути унікальним номером облікового запису Джона.


4
Порівнювати REST з CRUD - це серйозна помилка. POST не має означати CREATE.

12
Серйозна помилка? Я знаю, що існують відмінності між PUT та POST, але є вільне відображення до CRUD. "Серйозно"?
Тед Джонсон

3
Так, серйозно. CRUD - це спосіб структурування зберігання даних; REST - це спосіб структурування потоку даних додатків. Ви можете робити CRUD на REST, але ви не можете REST на CRUD. Вони не рівноцінні.
Джон Ватт

20

Велике питання, що REST здебільшого пояснюється прикладами, схожими на бази даних, де щось зберігається, оновлюється, витягується, видаляється. Таких прикладів небагато, коли сервер повинен якось обробляти дані. Я не думаю, що Рой Філдінг не включав жодної у свою тезу, яка все-таки була заснована на http.

Але він говорить про "передачу репрезентативного стану" як державну машину, при цьому посилання переходять до наступного стану. Таким чином, документи (представлення) відстежують стан клієнта, замість того, щоб сервер це робив. Таким чином, не існує штату клієнта, а лише стан, у зв'язку з яким посиланням ви перебуваєте.

Я думав про це, і мені здається розумним, щоб змусити сервер щось обробити для вас, коли ви завантажуєте, сервер автоматично створював би пов’язані ресурси та надав вам посилання на них (насправді, це не буде Вам не потрібно автоматично створювати їх: він може просто повідомити вам посилання, і він створюватиме їх лише тоді, коли і якщо ви будете слідувати за ними - ліниве створення). А також, щоб дати вам посилання для створення нових пов’язаних ресурсів - пов’язаний ресурс має той самий URI, але довший (додає суфікс). Наприклад:

  1. Ви завантажуєте ( POST ) представлення концепції транзакції з усією інформацією. Це схоже на дзвінок RPC, але він справді створює "запропонований ресурс транзакцій". наприклад URI: /transaction глюки призведуть до створення декількох таких ресурсів, кожен з яких має інший URI.
  2. У відповіді сервера вказується URI створеного ресурсу, його представлення - сюди входить посилання ( URI ) для створення пов'язаного ресурсу нового "здійсненого ресурсу транзакцій". Інші пов'язані ресурси - це посилання для видалення запропонованої транзакції. Це стани в державному апараті, за якими може дотримуватися клієнт. За логікою, це частина ресурсу, створеного на сервері, за винятком інформації, яку надає клієнт. наприклад , ідентифікатори URI: /transaction/1234/proposed, /transaction/1234/committed
  3. Ви переходите на посилання, щоб створити "здійснений ресурс транзакцій" , який створює цей ресурс, змінюючи стан сервера (залишки двох рахунків) **. За своєю природою цей ресурс може бути створений лише один раз і не може бути оновлений. Тому глюки, які здійснюють багато транзакцій, не можуть виникнути.
  4. Ви можете отримати ці два ресурси, щоб побачити, який їх стан. Якщо припустити, що POST може змінити інші ресурси, пропозиція тепер буде позначена як "скоєна" (або, можливо, взагалі недоступна).

Це схоже на те, як діють веб-сторінки, на кінцевій веб-сторінці сказано: "Ви впевнені, що хочете це зробити?" Ця кінцева веб-сторінка сама по собі являє собою стан транзакції, що включає посилання для переходу до наступного стану. Не лише фінансові операції; також (наприклад) попередній перегляд, а потім здійснювати на wikipedia. Я думаю, відмінність REST полягає в тому, що кожен етап у послідовності станів має явну назву (його URI).

У реальних операціях / продажах часто існують різні фізичні документи на різних стадіях угоди (пропозиція, замовлення на придбання, квитанція тощо). Ще більше для придбання будинку, з поселенням тощо.

OTOH Для мене це схоже на гру з семантикою; Мені незручно з номіналізацією перетворення дієслів у іменники, щоб зробити його RESTful, "тому що він використовує іменники (URI) замість дієслів (RPC дзвінки)". тобто іменник "скоєний ресурс транзакції" замість дієслова "здійснити цю транзакцію". Я здогадуюсь, одна з переваг номіналізації полягає в тому, що ви можете посилатися на ресурс по імені, замість того, щоб вказувати його якось іншим способом (наприклад, збереження стану сеансу, тому ви знаєте, що таке "ця" транзакція ...)

Але важливе питання: в чому переваги такого підходу? тобто яким чином цей стиль REST кращий, ніж стиль RPC? Чи корисна для веб-сторінок техніка також корисна для обробки інформації, крім магазину / отримання / оновлення / видалення? Я думаю, що ключовою перевагою REST є масштабність; одним із аспектів цього є не необхідність чітко підтримувати стан клієнта (але робить його неявним в URI ресурсу, а наступні констатують як посилання в його представленні). У цьому сенсі це допомагає. Можливо, це теж допомагає в шаруванні / трубопроводі? OTOH тільки один користувач буде дивитися на свою конкретну транзакцію, тому немає переваги в кешуванні її, щоб інші могли її прочитати, велика виграш для http.


Чи можете ви поясніть, як "не потребує утримання стану клієнта" допомагає масштабованості? Що за масштабованість? Масштабованість у якому сенсі?
jhegedus

11

Якщо ви відстоюєте підсумовувати обговорення тут, то цілком зрозуміло, що REST не підходить для багатьох API, особливо коли взаємодія клієнт-сервер за своєю суттю є державною, як це стосується нетривіальних транзакцій. Навіщо стрибати через усі запропоновані обручі для клієнта та сервера обох, щоб педантично дотримуватися певного принципу, який не відповідає проблемі? Кращий принцип - дати клієнту найпростіший, природний, продуктивний спосіб скласти програму.

Підсумовуючи це, якщо ви дійсно робите багато транзакцій (типів, а не екземплярів) у своїй програмі, ви дійсно не повинні створювати API RESTful.


9
Правильно, але що має бути альтернативою у випадку розподіленої архітектури мікропослуг?
Вітамон

11

Я відхилився від цієї теми 10 років. Повернувшись, я не можу повірити, що релігія маскується як наука, до якої ти переходиш, коли Google відпочинок + надійний. Плутанина - міфічна.

Я б поділив це широке питання на три:

  • Послуги нижче. Будь-який веб-сервіс, який ви розробляєте, матиме сервіси нижче, які ви використовуєте, і чий синтаксис транзакцій вам не залишається іншого вибору, як слідкувати. Вам слід спробувати приховати все це від користувачів вашої послуги та переконатися, що всі частини вашої операції успішно перервані або не вдаються до групи, а потім поверніть цей результат своїм користувачам.
  • Ваші послуги. Клієнти хочуть однозначних результатів викликів веб-служб, і звичайна схема REST прямих запитів POST, PUT або DELETE безпосередньо на суттєвих ресурсах вважає мене поганим і легко вдосконаленим способом надання цієї впевненості. Якщо ви дбаєте про надійність, вам потрібно визначити запити про дії. Цей ідентифікатор може бути орієнтиром, створеним для клієнта, або початковим значенням реляційного БД на сервері, це не має значення. Для ідентифікаторів, згенерованих сервером, використовуйте запит-відповідь "перед політом" для обміну ідентифікатором дії. Якщо цей запит не вдається або половина успішна, немає проблем, клієнт просто повторює запит. Невикористані ідентифікатори не завдають шкоди.

    Це важливо, оскільки це дозволяє всі наступні запити бути повністю ідентичними, в тому сенсі, що якщо вони повторюються n разів, вони повертають один і той же результат і більше нічого не стають. Сервер зберігає всі відповіді проти ідентифікатора дії, і якщо він бачить той самий запит, він повторює ту саму відповідь. Більш повна обробка візерунка знаходиться в цьому документі google . Документ пропонує реалізацію, яка, я вважаю (!), Широко відповідає принципам REST. Експерти напевно скажуть мені, як це порушує інших. Ця модель може бути корисно використана для будь-якого небезпечного дзвінка на ваш веб-сервіс, незалежно від того, чи пов’язані трансакції нижче.
  • Інтеграція вашої послуги в "транзакції", що контролюються поточними службами. У контексті веб-служб повні ACID-транзакції вважаються зазвичай не вартими зусиль, але ви можете значно допомогти споживачам вашої послуги, надавши скасування та / або підтвердження посилань у вашій відповіді про підтвердження, і таким чином домогтися транзакцій за рахунок компенсації .

Ваша вимога є принциповою. Не дозволяйте людям сказати вам, що ваше рішення не коштує. Судіть про їх архітектуру з урахуванням того, наскільки добре і як просто вони вирішують вашу проблему.


9

Вам доведеться зафіксувати свій власний тип ідентифікатора транзакцій управління TX. Тож було б 4 дзвінки:

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)

Вам доведеться керувати зберіганням дій у БД (якщо збалансовано завантаження) або в пам'яті чи іншому, а потім обробляти фіксацію, відкат, час очікування.

Насправді не СВЯТО День у парку.


4
Я не вважаю це особливо хорошою ілюстрацією. Вам потрібні лише два кроки: Створити транзакцію (створює транзакцію у стані "очікування") та Здійснити транзакцію (здійснює, якщо вона не працює, та переміщує ресурс у стан, який перебуває у відведеному стані або відкочується).
Джон Ватте

2

Я думаю, що в цьому випадку цілком прийнятно порушувати чисту теорію REST в цій ситуації. У будь-якому випадку, я не думаю, що насправді в REST є щось, що говорить, що ви не можете торкатися залежних об’єктів у ділових випадках, які цього вимагають.

Я дійсно думаю, що не варто зайвих обручів, через які ви стрибали б, щоб створити спеціальний менеджер транзакцій, коли ви могли просто скористатися базою даних для цього.


2

Перш за все, переказ грошей - це те, що ви не можете зробити за один виклик ресурсу. Дія, яку ви хочете зробити - це пересилання грошей. Таким чином, ви додаєте ресурс переказу грошей на рахунок відправника.

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

Зроблено. Вам не потрібно знати, що це транзакція, яка повинна бути атомною і т. Д. Ви просто перераховуєте гроші. надсилати гроші від А до Б.


Але для рідкісних випадків тут загальне рішення:

Якщо ви хочете зробити щось дуже складне із залученням багатьох ресурсів у визначеному контексті з безліччю обмежень, які насправді перетинають бар'єр між тим, чому і чому (бізнес та знання про впровадження), вам потрібно передати стан. Оскільки REST має бути без громадянства, вам як клієнту потрібно передати стан.

Якщо ви передаєте стан, вам потрібно сховати інформацію всередині клієнта. Клієнт не повинен знати внутрішню інформацію, необхідну лише впровадженню, але не несе інформації, що стосується бізнесу. Якщо ця інформація не має ділової цінності, держава повинна бути зашифрована та використовувати метафору, як маркер, пропуск чи щось подібне.

Таким чином можна передати внутрішній стан навколо, а за допомогою шифрування та підписання системи все ще може бути захищеним та надійним. Пошук потрібної абстракції для клієнта, чому він передає інформацію про стан - це щось, що залежить від дизайну та архітектури.


Реальне рішення:

Пам'ятайте, що REST говорить HTTP, а HTTP поставляється з концепцією використання файлів cookie. Ці файли cookie часто забуваються, коли люди говорять про API REST та робочі процеси та взаємодії, що охоплюють декілька ресурсів чи запитів.

Згадайте, що написано у Вікіпедії про файли cookie HTTP:

Файли cookie були розроблені як надійний механізм веб-сайтів для запам'ятовування відомостей про стан (наприклад, предметів у кошику для покупок) або для запису активності перегляду користувача (включаючи натискання певних кнопок, вхід у систему чи запис, які сторінки відвідував користувач наскільки назад, як місяці чи роки тому).

Тому в основному, якщо вам потрібно передати стан, використовуйте cookie. Він розроблений саме з тієї ж причини, це HTTP і тому він сумісний з REST за дизайном :).


Краще рішення:

Якщо ви говорите про клієнта, який виконує робочий процес, що включає декілька запитів, зазвичай ви говорите про протокол. Кожна форма протоколу постачається з набором передумов для кожного потенційного кроку, як-от виконайте крок А, перш ніж ви можете виконати B.

Це природно, але опромінення протоколу для клієнтів робить все більш складним. Щоб уникнути цього, просто подумайте, що ми робимо, коли нам доведеться робити складні взаємодії та речі в реальному світі. Ми використовуємо Агент.

Використовуючи метафору Агента, ви можете надати ресурс, який може виконати всі необхідні для вас дії, і зберегти фактичне завдання / інструкції, на які він діє, у своєму списку (тому ми можемо використовувати POST на агенті чи «агентстві»).

Складний приклад:

Купівля будинку:

Вам потрібно довести свою достовірність (як, наприклад, надання ваших даних про поліцейські записи), вам потрібно забезпечити фінансові реквізити, вам потрібно придбати фактичний будинок за допомогою адвоката та довіреної третьої сторони, яка зберігає кошти, переконатися, що будинок зараз належить вам і додайте речі для покупки у свої податкові записи тощо (як приклад, деякі кроки можуть бути неправильними чи будь-якими іншими).

Ці кроки можуть зайняти кілька днів, деякі можна зробити паралельно тощо.

Для цього ви просто даєте агенту завдання придбати будинок типу:

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

Зроблено. Агентство надсилає вам довідку, яку ви можете використовувати для перегляду та відстеження стану цієї роботи, а решта робиться автоматично агентами агентства.

Подумайте, наприклад, про помилку відслідковування помилок. В основному ви повідомляєте про помилку і можете використовувати ідентифікатор помилки, щоб перевірити, що відбувається. Ви навіть можете скористатися сервісом для прослуховування змін цього ресурсу. Місія виконана


1

Ви не повинні використовувати транзакції на стороні сервера в REST.

Один з REST протипоказань:

Без громадянства

Зв'язок клієнт-сервер ще більше обмежується тим, що на сервері між запитами не зберігається контекст клієнта. Кожен запит будь-якого клієнта містить всю інформацію, необхідну для обслуговування запиту, і будь-який стан сеансу зберігається у клієнта.

Єдиний RESTful спосіб - це створити журнал повторення транзакцій і помістити його в стан клієнта. За допомогою запитів клієнт надсилає журнал повторень, а сервер повторює транзакції і

  1. повертає транзакцію назад, але надає новий журнал повторень транзакцій (на крок далі)
  2. або нарешті завершити транзакцію.

Але, можливо, простіше використовувати серверну технологію, яка підтримує транзакції на стороні сервера.


Цитата - із вікіпедії REST. Це справжнє джерело чи Вікіпедія дістала його звідкись? Хто скаже, що таке клієнтський контекст та який серверний контекст?
bbsimonbb

1

Я вважаю, що у випадку використання унікального ідентифікатора, згенерованого на клієнті, гарантує, що іконка з'єднання не передбачає подвійності, збереженої API.

Я думаю, що використання поля GUID, створеного клієнтом, разом із об’єктом передачі та забезпечення того, що той самий GUID не буде знову введено, було б більш простим рішенням щодо питання банківського переказу.

Не знаєте про складніші сценарії, такі як багаторазове бронювання авіаквитків або мікро архітектури.

Я знайшов документ про цю тему, що стосується досвіду роботи з атомністю транзакцій у службах RESTful .


0

У простому випадку (без розподілених ресурсів) ви можете розглядати транзакцію як ресурс, де акт її створення досягає кінцевої мети.

Отже, для передачі між <url-base>/account/aі <url-base>/account/b, ви можете опублікувати наступне на <url-base>/transfer.

<переклад>
    <from> <url-base> / account / a </from>
    <to> <url-base> / рахунок / b </to>
    <кількість> 50 </amount>
</transfer>

Це створило б новий ресурс передачі і поверне нову URL-адресу передачі - наприклад <url-base>/transfer/256.

У момент успішної публікації на сервері виконується «справжня» транзакція, а сума знімається з одного рахунку та додається до іншого.

Це, однак, не охоплює розподілену транзакцію (якщо, скажімо, "a" проводиться в одному банку за однією службою, а "b" - в іншому банку за іншою службою) - крім того, щоб сказати "спробуйте викласти все операції способами, які не потребують розподілених транзакцій ".


2
Якщо ви не можете "сформулювати всі операції способами, які не вимагають розподілених транзакцій", то вам дійсно потрібна двофазна фіксація. Найкраща ідея, яку я міг би знайти для здійснення двофазної фіксації на REST, це rest.blueoxen.net/cgi-bin/wiki.pl?TwoPhaseCommit , що важливо не псує простір імен URL-адрес і дозволяє двофазному виконувати зобов’язання чиста семантика REST.
Phasmal

3
Інша проблема з цією пропозицією полягає в тому, що якщо кеш-пам’ять і POST двічі відбувається, ви отримуєте дві передачі.
Джон Ватте

Щоправда, у цьому випадку вам потрібно буде пройти процес у два етапи - створити ресурс "передачі" з унікальною URL-адресою, а потім додати до нього дані передачі як частину комісії (дві частини, як згадується в інших відповідях). Звичайно, це може бути виражене як створення ресурсу "транзакції", а потім додавання до нього операції "передачі".
Phasmal

-3

Я думаю, ви могли б включити TAN в URL / ресурс:

  1. PUT / транзакція для отримання ідентифікатора (наприклад, "1")
  2. [PUT, GET, POST, що завгодно] / 1 / рахунок / bob
  3. [PUT, GET, POST, що завгодно] / 1 / рахунок / рахунок
  4. УВАГА / транзакція з ідентифікатором 1

Просто ідея.


Я бачу дві проблеми з таким підходом: 1) Це означає, що ви не можете отримати доступ до ресурсу поза транзакцією (хоча, можливо, це не є великою справою). 2) Жодна з відповідей поки що не торкнулася того факту, що сервер перестає бути без громадянства, хоча я підозрюю, що з цим нічого не можна зробити.
Гілі

Ну, / 1 / акаунт / bob та / account / bob - це лише два різних ресурси. :) І RE: без громадянства, це означає, що ресурс завжди доступний і не залежить від попереднього запиту. Оскільки ви просили угоди, так, це не так. Але знову ж таки, ви хотіли угоди.
До

1
Якщо клієнту доводиться збирати URI, то ваш API не RESTful.
aehlke

1
Насправді я не можу зрозуміти вас Якщо ви трактуєте транзакцію як ресурс (як у наведеному вище прикладі), ви просто припиняєте обробляти транзакцію в класичному розумінні і використовуєте її "належним чином REST", що ще більше спрощує програмування транзакційних процесів. Наприклад, ви можете включити href до транзакції у ваші відповіді, щоб обійти переміщення у розподіленому середовищі на сервері, він все ще без стану (це просто ресурс, чи не так?), І ви можете будь-коли реалізувати механізм транзакцій. хочете (що, якщо у вас немає
баз

1
Так чи інакше, якщо ви просто перестанете думати SQL / SOAP і почнете думати HTTP (як це робить браузер), все стає просто
Маттіас Хринізак
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.