Косою косою рисою в API RESTful


60

У мене були дискусії щодо того, що робити з косою косою рисою в API RESTful.

Скажімо, у мене є ресурс, званий собаки, і підпорядковані ресурси для окремих собак. Тому ми можемо зробити наступне:

GET/PUT/POST/DELETE http://example.com/dogs
GET/PUT/POST/DELETE http://example.com/dogs/{id}

Але що ми робимо з таким особливим випадком:

GET/PUT/POST/DELETE http://example.com/dogs/

Моя особиста думка полягає в тому, що це говорить про надсилання запиту на окремий ресурс собаки з id = null. Я думаю, що API повинен повернути 404 для цього випадку.

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

Хтось знає остаточну відповідь?


2
Я подумав, що НАЙКРАЩИЙ спосіб розрізнити собаку / ід та собаку (маючи на увазі всіх собак).
пдр

З книги «RESTful Web Services» - підпорядковані ресурси: ресурси, які існують стосовно якогось іншого «батьківського» ресурсу, наприклад, собаки / {id} База даних із підтримкою веб-сторінок може відкривати таблицю як ресурс, а окрема база даних - рядки як її підпорядковані ресурси .
Gaz_Edge

Це доступ до ресурсу для собаки, слід проігнорувати останню косу рису, а це означає, що він повинен отримати заборонену відповідь на спробу видалити те, до чого видалення не слід застосовувати. Я здогадуюсь, що 404 також прийнятний. Невже це має значення?
Бенджамін Груенбаум

Я не дотримуюся - хто сказав, що ви не можете видалити собак? Якщо ви видалите собак, вона видаляє себе та всіх окремих собак. Ось чому я вважаю, що дозволити дзвінки собакам / ризиковано. Що робити, якщо клієнт мав намір видалити окрему собаку, але випадково відмовився від {id}. Результатом було б, що всі собаки будуть видалені. Набагато безпечніше припустити, що він просить {id} null і повернути 404
Gaz_Edge

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

Відповіді:


50

Ніщо з цього не є авторитетним (оскільки REST не має точного значення). Але з оригінальної статті на REST повна (не закінчується на /) URL-адреса називає ресурс, а одна, що закінчується на косою рискою '/', - це група ресурсів (напевно, не сформульована так).

Отриманий URL з косою косою рискою повинен містити список доступних ресурсів.

GET http://example.com/dogs/          /* List all the dogs resources */

PUT на URL-адресу з косою рисою повинен замінити всі ресурси.

PUT http://example.com/dogs/          /* Replace all the dogs resources */

ВИДАЛЕНО за URL-адресою з косою рисою має видалити всі ресурси

DELETE http://example.com/dogs/       /* Deletes all the dogs resources */

POST за URL-адресою з косою рисою повинен створити новий ресурс, а потім можна отримати згодом доступ. Щоб відповідати, новий ресурс повинен бути в цьому каталозі (хоча тут чимало RESTful архітектур).

POST http://example.com/dogs/        /* Creates a new dogs resource (notice singular) */

тощо.

Сторінка вікі з цього питання, здається, це добре пояснює:

Див. Приклад https://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_Web_services .


Він також відповідає нормальній моделі шлях / URL, де каталоги часто записуються із заднім /
числом

4
Отже, що має відбутися, якщо ви отримаєте доступ до групи ресурсів без останнього /?
oberlies

1
@oberlies: Це залежить від контексту. Не існує жорстких і швидких правил, лише найкраща практика. Завжди є висловлювання до правила, і це повинно означати те, що ви очікуєте від нього. У наведеному вище прикладі: GET http://example.com/dogsможе повертатися метаінформація про собак (не сам список, а метаінформація про список собак). Можливо, або може бути його помилка.
Martin York

1
As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.Це не єдине місце, де пропонується не використовувати тренувальну косу
рису

@Laiv Я не згоден з настроями. Але, будь ласка, зв’яжіть більш авторитетну посилання (це слабке посилання).
Мартін Йорк

17
Does anyone know the definitive answer?

Немає жодного, оскільки немає офіційного документа про те, що потрібно для того, щоб послуга вважалася ВІДПОВІДНОЮ.

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



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

@Gaz_Edge: У REST example.com/dogs- це ресурс, повністю незалежний від будь-якого ресурсу example.com/dogs/X. Таким чином, DELETE example.com/dogsне повинен видаляти всіх собак / * (хоча це може, якщо це семантика). Але DELETE example.com/dogs/повинен видалити всіх собак / *.
Martin York

3
Я ще раз зазначу, що оскільки не існує остаточного набору правил щодо того, що РЕСТАВНО, що відбувається, коли ви ВИДАЛИТИ / собак або / собак /, буде грунтуватися на тому, що ви очікуєте від споживачів вашого API. Чи ймовірно, що вони насправді хочуть видалити всіх собак одним запитом? Якщо так, то реалізуйте це так, якщо ні, то дайте відповідь 405 Метод не дозволений.
Майк

1
Я знаю, що це стара нитка, але останнім часом я сам про це цікавився. Для чого це коштує, в OS X лікує Bash оболонки foo, foo/і foo////однаково. Це, здається, викреслює порожні сегменти шляху. Отже, якщо ви дотримуєтесь того ж підходу зі службою REST, dogsі ви dogs/посилаєтесь на те саме.
Грег Браун

2

Два способи.

Спосіб 1

Завжди використовуйте косої риски для будь-якого ресурсу, який може містити дітей.

Просто розгляньте "GET" у каталозі public_html з файлами.

Неможливо, коли файл hello.html - це файл:

/hello.html
/hello.html/youagain.html

Але можливо, коли hello.html - це каталог:

/hello.html/     (actually /hello.html/index.html)
/hello.html/youagain.html

Тож якщо "hello.html" може колись мати дітей, то це завжди і назавжди "/hello.html/" і "/hello.html/index.html" (або просто /hello.html/) - це список цих дітей .

Спосіб 2

Бути розумним".

$ find
.
./hello.html
./hello.html/index.html

Команда find не хвилює тип hello.html. Каталог або файл, кому це цікаво, це ім'я об'єкта. Коли ми пишемо "cp youagain.html hello.html", cp може зрозуміти, як поводитися з hello.html. cp розумний. Ваш веб-сервер теж розумний. Він має бібліотеку обробки контурів. Він має маршрутизацію. Він може стати та повідомити, чи є ім'я об'єктом чи каталогом. Він може перенаправити благ на благ / або навіть просто подати однакову відповідь для обох. Це дивовижно !!! шлях. Стільки технологій. Хто б хотів просто об'єднати рядки шляху, коли ми могли все це зробити ???

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