Як я повинен розробити замовлений ресурс списку в спокійному сервісі?


11

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

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

Як я повинен розробити спокійне обслуговування упорядкованого списку ресурсів?

Зокрема, як я повинен розробити listта itemмодель спокійного ресурсу? Найпоширеніший дизайн, який я бачив - це itemорганізація, яка має orderабо має positionвласність. Ще один підхід, який я чув, - це подвійно пов'язаний список предметів.

Що таке підхід, який не надто записує в базу даних і, як правило, швидко оновлюється та читається для клієнтів? Як слід виставляти кінцеві точки?


З цікавості, чому важливо спеціально повернути упорядкований список?
Адам Уеллс

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

Відповіді:


14

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

Слід уникати використання подвійно пов'язаних списків, оскільки легко випадково зробити посилання непослідовними, а в кінцевому підсумку - циклічним графіком або деревом.

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

Якщо у вас є лише до кількох сотень елементів у списку, просто перенесіть увесь список у запиті. Припускаючи, що ми хочемо змінити порядок того, [1, 2, 3, 4]де члени списку є ідентифікаторами, ми могли б

POST /url/of/the/list
Content-type: application/json
...

[1, 2, 4, 3]

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

Якщо список великий і елементи зазвичай запитуються індивідуально, ви можете дозволити індекс у URL-адресі:

GET /page/7

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

Якщо список дуже великий, ви можете розкрити ArrayListподібні операції, такі як insertабо push/ append. Я міг уявити собі такий дзвінок, як

POST /url/of/the/list?at=1357;mode=insert
...

description of the item to insert

Якщо переупорядкування є загальним випадком використання та переупорядкування слід здійснити негайно, то ви можете запропонувати відповідну кінцеву точку у своєму API:

POST /url/of/the/list/reorder-item?from=783;to=1357

Якщо упорядкований список має бути зроблений явно, буде простіше передати новий порядок як документ JSON, див. Вище.

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


1
Зауважте, що підхід "замінити весь список" може стати проблематичним, якщо кілька клієнтів вносять зміни. Якщо ви не дотримуєтесь жодних запобіжних заходів, ви можете перезаписати чужі зміни ("переможе останнє перед написанням").
oefe

Операції, подібні до списку, не повинні мати цю проблему за умови, що параметри (у, від, до) є ідентифікаторами, а не індексами списку
oefe

2

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

Цей підхід запропонував перемістити товар в порядку замовлення:

POST / url / of / the / list / reorder-item? From = 783; to = 1357

Це може залежати від умов перегонів, якщо ви не маєте СЕРІАЛЬНОГО транзакцій. Рівень READ_COMMITTED за замовчуванням у більшості БД не усуне умову гонки!

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.