Коли використовувати вкладені ресурси в API RESTful


16

У мене є два ресурси: користувачі та посилання.

Користувачі можуть мати декілька посилань, пов’язаних з ними. Я розробив свій RESTful API, щоб ви могли отримати посилання, пов’язані з користувачем, на наступному URI:

/users/:id/links

Однак мені завжди потрібно мати URI для лише посилань - іноді, можливо, я хочу всіх посилань, незалежно від користувача.

Для цього я маю:

/links

Це добре звучить? Маєте два URI для посилань?

Цікаво, чи варто мені замість цього звертатися до посилань для користувача з URI, наприклад:

/links/user/:id або /links/?user=:id

Таким чином, у мене є лише один ресурс для посилань.


3
Хм .. Цей здається більш елегантним:/links/user/:id
TheMarceloR

7
@theMarceloR: Це єдиний із трьох прикладів, які я не вважаю особливо зрозумілими. Це ресурс для посилання чи користувача? URI набагато менш неоднозначний, використовуючи або метод вкладеного ресурсу ( /users/:id/links), або метод рядка запиту ( /links/?user=:id), оскільки він насправді є запитом. /links/user/:idможе виглядати приємно та / або простіше прокласти маршрут у деяких рамках, але насправді це досить заплутано.
Aaronaught

Відповіді:


16

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

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

/links -- all links
/links/:linkid -- a particular link

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

/links?user=/users/:userid

Це також дозволяє полегшити склад фільтрів:

/links?user=/users/10&since=2013-01-01

І це легко зрозуміти концептуально - у вас є колекція предметів, і ви додаєте до неї фільтри.

Незважаючи на це, у цьому підході немає нічого більш "ВІДКРИТЕ", ніж будь-яка інша схема іменування URI. Це лише умова, яку ми визнали людиною, зрозумілою та зрозумілою для нас, розробникам, зрозумілою та прийнятною. REST не хвилює, що ви вкладете в свої ідентифікатори ресурсів.


1
"Усі ресурси, де немає чіткого права власності, щоб не вкладати", звучить як хороше правило. Дякую купу.
Олівер Джозеф Еш

5
Я б сказав , що там є що - то неправильно з наявністю декількох ресурсів для того ж фізичної особи, але це не на самому ділі , що це таке. Кожне окреме посилання має канонічну URL-адресу (посилання /: id), тоді як кожен із наведених вище ресурсів насправді є єдиним ресурсом (/ посиланнями) із застосованими фільтрами. Крім того, мене дивує ?user=users/:useridрядок запиту; що з цим просто не так ?userid=:userid?
Aaronaught

2
@Aaronaught: причина дотримуватися урі замість оголених ідентифікаторів полягає в тому, що клієнти можуть однаково ставитися до всіх ідентифікаторів ресурсів, тобто клієнту потрібно лише знати, що «цей користувач ідентифікується за допомогою "/*******"; де *'s непрозорі. але той самий ідентифікатор завжди може використовуватися для посилання на цей ресурс (як у посиланнях), для отримання найновішої версії цього ресурсу тощо. вміст цього урі розуміється лише сервером початківців. Це також означає, що якщо ідентифікатори потрібно змінити, скажімо /realm/:businessid/users/:id, клієнт взагалі не зміниться.
SingleNegationElimination

@TokenMacGuy: Вибачте, я не розумію жодної частини вашого коментаря. Яка практична різниця між /users/:userid/linksі /links?userid=:userid? В обох випадках ідентифікатори не змінюються, вони отримують поточну версію цього ресурсу, і клієнт ставиться до них однаково. Канонічна URL-адреса для цього не існує, оскільки це не ресурс, це запит, тому це лише два різних типи синтаксису запитів. Мені також не зрозуміло, як клієнту не потрібно було б змінюватись, якщо структура URL-адреси зміниться; це вважається зривною зміною REST, якщо не встановлено 301.
Aaronaught

1
@Aaronaught: Я, можливо, неправильно зрозумів вашу стурбованість. Припустимо, що /linksпідтримує інтерфейс запитів, /links?user=/users/123дозволяє підходити чорний ящик до ідентифікаторів ресурсів у клієнтів /links?userid=123. остання вимагає від клієнта розуміння, що таке користувальницький і як його отримати, імовірно, з ресурсу, отриманого від /users/123або /links/456/user. Перший означає, що клієнт може використовувати урі немодифікований; припустимо, що /links/.../userдає відповідь гіпермедіа (скажімо, Location:заголовками).
SingleNegationElimination

1

Тож я хвилююсь: / users /: userid / links повертає "посилання", АЛЕ якщо user_id не визначений, це має повернути 404.

Однак

/ посилання? userid =: userid потенційно може повернути порожній список (по суті, 200), який насправді є помилкою. І цілком можливо.

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

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