Як пошук вписується в інтерфейс RESTful?


137

При проектуванні інтерфейсу RESTful семантика типів запитів вважається життєво важливою для дизайну.

  • GET - Список колекції або отримання елемента
  • PUT - Замініть колекцію чи елемент
  • POST - Створення колекції або елемента
  • DELETE - Ну, ерм, видалити колекцію чи елемент

Однак, схоже, це не охоплює поняття "пошук".

Наприклад, при розробці набору веб-служб, які підтримують сайт пошуку роботи, можливо, ви будете мати такі вимоги:

  • Отримати індивідуальну роботу
    • GET дляdomain/Job/{id}/
  • Створити рекламу роботи
    • POST вdomain/Job/
  • Оновити оголошення про роботу
    • ПУТ вdomain/Job/
  • Видалити оголошення про роботу
    • ВИДАЛИТИ доdomain/Job/

"Отримати всі робочі місця" також просто:

  • GET дляdomain/Jobs/

Однак як робота "пошуку" потрапляє до цієї структури?

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

  • GET дляdomain/Jobs/

Однак пошук може бути складним, і цілком можливо здійснити пошук, який генерує довгий рядок GET. Тобто, посилаючись на питання SO , тут виникають проблеми, що використовують рядки GET довше ніж 2000 символів.

Приклад може бути у гранітному пошуку - продовження прикладу "робота".

Я можу дозволити пошук по гранях - "Технологія", "Назва роботи", "Дисципліна", а також ключові слова з вільним текстом, вік роботи, місцезнаходження та зарплата.

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

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

У цій ситуації може бути бажаним перемістити PUT або POST, щоб гарантувати правильне надсилання даних пошуку. Наприклад:

  • POST вdomain/Jobs/

Але семантично це інструкція створити колекцію.

Ви могли б також сказати , що ви будете висловлювати це як створення пошуку:

  • POST вdomain/Jobs/Search/

або (як це запропоновано спалювальною схемою нижче)

  • POST вdomain/JobSearch/

Семантично це може здатися сенсом, але ви насправді нічого не створюєте, ви запитуєте дані.

Отже, семантично це GET , але GET не гарантовано підтримує те, що потрібно.

Отже, питання полягає в тому, щоб намагатися дотримати максимально вірний дизайн RESTful, домагаючись того, щоб я тримався в межах обмежень HTTP, що є найбільш підходящим дизайном для пошуку?


3
Я часто маю намір використовувати GET domain/Jobs?keyword={keyword} . Це добре працює для мене :) Я сподіваюся, що SEARCHдієслово стане стандартним. programmers.stackexchange.com/questions/233158/…
Knerd

Так, я можу бачити, що для тривіального прикладу не існує проблеми. Але в інструменті, який ми будуємо, насправді не так неймовірно, що ми б закінчилися складним пошуком, який призводить до отримання GET-рядку довше 2000 символів. Що потім?
Роб Бейлі

Насправді дуже хороший момент. А як же вказати технологію стиснення?
Кнерд

2
GET з тілом дозволений специфікацією HTTP, може підтримуватися або не підтримуватися середнім програмним забезпеченням (іноді немає); Це з'являється на Stackexchange періодично. stackoverflow.com/questions/978061/http-get-with-request-body
Роб

2
У кінцевому підсумку POST JobSearch створив фактичну пошукову структуру та повертає taskSearchId. Тоді GET jobs? JobSearch = jobSearchId повертає фактичну колекцію завдань.
Церад

Відповіді:


93

Не слід забувати, що GET- запити мають деякі переваги перед іншими рішеннями:

1) GET-запити можна скопіювати з URL-адреси, вони засвоюються пошуковими системами, вони "дружні". Якщо "дружній" означає, що звичайно GET-запит не повинен змінювати нічого у вашій програмі (idempotent) . Це стандартний випадок для пошуку.

2) Усі ці поняття дуже важливі не лише з боку користувача та пошукової системи, а з архітектурної та дизайнерської точки зору API .

3) Якщо ви створюєте обхідний шлях з POST / PUT ви будете мати проблеми , які ви не думаєте прямо зараз. Наприклад, для веб-переглядача натисніть кнопку "Назад" / оновити сторінку / історію. Це, звичайно, можна вирішити, але це буде чергове вирішення, потім ще одне і інше ...

Враховуючи все це, моєю порадою було б:

a) Ви повинні мати можливість поміститись у свій GET за допомогою розумної структури параметрів . У крайньому випадку, ви навіть можете скористатися такою тактикою, як цей пошук в Google, де я встановив безліч параметрів, як і раніше, це дуже короткий URL.

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


Особисто я б спробував битися з усіма моїми кігтями, щоб це зробити з a), і коли вся надія втрачена, я б повзав назад зі сльозами на очах до варіанту b) .


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

@RobBaillie Ye, браузер був лише випадком використання. Я хотів висловити той факт, що ваш пошук в цілому представлений рядком URL. Що має великий комфорт у користуванні, а також інші моменти у відповіді.
p1100i

У пункті б, це проста зміна мого власного посилання на POST на domain/Jobs/Search/, можливо, domain/JobsSearch/замість цього, або ви мали на увазі щось інше? Ви можете уточнити?
Роб Бейлі

7
Чому у мене складається враження, що REST досить часто є частиною проблеми, а не частиною рішення?
JensG

1
"GET-запит не повинен змінювати нічого у вашій програмі (idempotent)", хоча GET є idempotent, тут відповідне слово " безпечно ". Idempotent означає, що робити GET на ресурсі двічі - це те саме, що робити GET на цьому ресурсі один раз. PUT також ідентичний, але не безпечний, наприклад.
Jasmijn

12

TL; DR: GET для фільтрації, POST для пошуку

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

Це, як правило, підсилюється, коли думаєш про те, що буде повернено. Зазвичай я використовую GET лише тоді, коли ресурс має переважно повний життєвий цикл (PUT, DELETE, GET, GET колекція) . Зазвичай у колекції GET я повертаю список URI, які є REST-ресурсами, що складають цю колекцію. У складному запиті я можу витягуватися з декількох ресурсів для побудови відповіді (думаю, що SQL приєднається), тому я не буду надсилати URI, а фактичні дані. Проблема в тому, що дані не будуть представлені в ресурсі, тому мені завжди доведеться повертати дані. Мені здається, це чіткий випадок вимагання POST.

-

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

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

POST - це метод уловлення для будь-якого, що, здається, не підходить під GET, PUT, DELETE тощо.

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

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

У будь-якому випадку послідовність, ймовірно, важливіша, ніж ви здійснюєте пошук у GET чи POST.

Сподіваюсь, це допомагає.


1
Оскільки REST призначений для абстрагування базової реалізації (наприклад, ресурс - це не обов'язково рядок у базі даних або файл на жорсткому диску, але це може бути що завгодно ), я не знаю, що це обов'язково має сенс використовувати POST над GET, коли справа доходить до виконання SQL-приєднань. Припустимо, у вас є школа шкіл і стіл дітей, і ви хочете клас (одна школа, кілька дітей). Ви можете легко визначити віртуальний ресурс і GET /class?queryParams. З точки зору користувача, "клас" завжди був річчю, і вам не потрібно було робити жодних дивних приєднань до SQL.
stevendesu

Немає різниці між "фільтруванням" та "пошуком".
Микола Шенкс

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

@stevendesu точно, тому я використовую POST для обох (створення пошуку) :-)
ymajoros

@ymajoros Якщо ви не зберігаєте десь пошукові терміни та результати пошуку, я не знаю, що POST має сенс семантично. Під час пошуку ви робите запит на інформацію, ви не надаєте нову інформацію для зберігання в будь-якому місці.
stevendesu

10

У REST визначення ресурсів дуже широке. Це дійсно, проте ви хочете зібрати деякі дані.

  • Корисно думати про пошуковий ресурс як про ресурс колекції. Параметри запиту, які іноді називають частиною URI, в якій можна шукати, звужують ресурс до предметів, які цікавлять клієнта.

Наприклад, основний URI Google вказує на ресурс колекції "посилання на кожен сайт в Інтернеті". Параметри запиту звужуються до сайтів, які ви хочете бачити.

(URI = універсальний ідентифікатор ресурсу, з яких URL = універсальний локатор ресурсів, де знайомий "http: //" формат за замовчуванням для URI. Отже, URL - це локатор, але в REST його добре узагальнити до ідентифікатора ресурсу . Люди користуються ними незмінно.)

  • Оскільки ресурс, який ви шукаєте у своєму прикладі, - це колекція робочих місць, є сенс пошуку

Отримати сайт / завдання? Type = blah & location = here & etc = тощо

(повернення) {jobs: [{job: ...}]}

А потім використовуйте POST, який є дієсловом додавання чи обробки, щоб додати нові елементи до цієї колекції:

Сайт / місця роботи

{робота: ...}

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

  • Для дійсно довгих або складних рядків запитів конвенція дає змогу надсилати їх як POST-запити. З'єднайте параметри запиту як пари імен / значень або вкладені об'єкти в структурі JSON або XML та надішліть його в тіло запиту. Наприклад, якщо ваш запит вклав дані замість купу імен / значень пар. Специфікація HTTP для POST описує її як додаток або дієслово. (Якщо ви хочете проплисти на лінійному кораблі через лазівку в REST, використовуйте POST.)

Я б використовував це як резервний план.

Те, що ви втрачаєте, хоч і зробите це: a) GET є нульовим - тобто це нічого не змінює - POST - ні. Отже, якщо виклик не вдається, проміжне програмне забезпечення не буде автоматично повторювати або кешувати результати та 2) з параметрами пошуку в тілі, ви більше не можете вирізати та вставити URI. Тобто URI не є конкретним ідентифікатором для потрібного пошуку.

Розрізняти "творити" від "пошуку". Є кілька варіантів, які відповідають практиці REST:

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

  • Оскільки семантика POST є процесом додавання АБО, ви можете визначити органи пошуку з корисним навантаженням. Як {робота: ...} проти {пошук: ...}. До логіки POST належить розмістити чи обробити її належним чином.

Це в значній мірі перевагу дизайну / реалізації. Я не думаю, що існує чітка конвенція.

Отже, як ви вже виклали, ідея полягає у визначенні ресурсу колекції для jobs

сайт / робочі місця

Пошук за допомогою параметрів GET +, щоб звузити пошук. Довгі або структуровані запити даних надходять у тіло POST (можливо, в окрему колекцію пошуку). Створіть за допомогою POST, щоб додати до колекції. І оновіть PUT до певного URI.

(FWIW умовою стилю з URI є використання всіх малих літер зі словами, розділеними дефісами. Але це не означає, що ви повинні робити це таким чином.)

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


Це цікава ідея - я б не розглядав можливість використання корисного навантаження для розмежування. Це, здається, трохи недоверше! Але я думаю, що схема URI насправді не містить дієслів - саме тип запиту визначає дієслово. Можливо корисне навантаження семантично ближче до типу запиту, ніж URI. Єдине питання - чи прозорий він для користувача API?
Роб Бейлі

Що стосується реалізації (ми використовуємо Node та Express), це може означати, що routeнасправді не можна впоратися з вибором обробки. Мені доведеться поглянути на це ...
Роб Бейлі

У мене таке ж відчуття кишки, що відокремлення його URI здається більш чистим. Я ніби йду назад і назад; це заклик рішення. Однак семантика HTTP дозволила б ввести його в тіло. Мені подобається сказати, що REST моделюється за всесвітньою мережею, а WWW будується за допомогою GET та POST.
Роб

8

Зазвичай я використовую запити OData, вони працюють як GET-дзвінок, але дозволяють обмежувати властивості, які повертаються, і фільтрувати їх.

Ви використовуєте такі жетони як $select=і $filter=тому ви отримаєте URI, який виглядає приблизно так:

/users?$select=Id,Name$filter=endswith(Name, 'Smith')

Ви також можете зробити підкачки , використовуючи $skipі $topі впорядкованість.

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


6
Цікаве посилання та варто переглянути, але чи вирішує він описану основоположну проблему, що запити GET не підтримують більше 2000 символів у рядку запиту, і цілком можливо, що запит може бути набагато довшим за це?
Роб Бейлі

@RobBaillie Я не думаю, що це все ще GET-дзвінок із рядком запиту. Я б запропонував використовувати OData куди завгодно, оскільки це стандарт для запиту джерел даних в Інтернеті та за кілька (якщо такі є) запит повинен бути настільки складним, що ви не зможете вмістити його в запиті 2000 символів, створіть конкретний кінцева точка, на яку Ви телефонуєте
Тревор Піллі,

Чи можете ви пояснити свій підхід щодо "конкретної кінцевої точки, до якої ви робите дзвінок GET"? Як ви можете уявити, що ця кінцева точка виглядатиме?
Роб Бейлі

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

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

5

Один із підходів, який слід розглянути, - це набір можливих запитів як ресурс колекції, наприклад /jobs/filters.

POSTзапити до цього ресурсу, з параметрами запиту в тілі, або створити новий ресурс або визначити існуючий еквівалентний фільтр і повертають URL , що містить його ідентифікатор: /jobs/filters/12345.

Ідентифікатор може бути використаний в запиті GET для завдань: /jobs?filter=12345. Подальші GETзапити на ресурсі фільтра повернуть визначення фільтра.

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

Недоліком такого підходу є те, що ви втрачаєте читабельність URL-адреси (хоча це може бути пом’якшенням, отримавши визначення, хоча GETзапит на ресурс фільтра). З цієї причини ви також можете підтримати той самий або підмножину параметрів запиту на /jobsресурсі, як і для ресурсу фільтра. Це може бути використане для коротших запитів. Якщо ця функція надана, для підтримки кешованості між двома типами фільтрації, при використанні параметрів запиту на /jobsресурсі реалізація повинна внутрішньо створити / повторно використати ресурс фільтра та повернути а 302або 303статус із зазначенням URL-адреси у вигляді /jobs?filter=12345.


Моя перша реакція на це полягає в тому, що, хоча це хороша інформація, це насправді лише зміна відповіді, яку надає @burninggramma. По суті це "створити нову сутність під назвою фільтр / пошук, зателефонувати, щоб створити її, а потім зателефонувати, щоб отримати її". Різниця полягає в тому, що виклик для його отримання більше нагадує дзвінок застосувати його до колекції. Цікаво. Однак і ваша відповідь, і відповідь горячої програми страждають від однієї проблеми - я не маю бажання створювати фільтри. Їх буде величезна кількість, і їх не потрібно зберігати, за винятком того, щоб зберегти RESTful реалізацію.
Роб Бейлі

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

Ви можете подолати необхідність зберігання фільтрів, просто ... не зберігаючи їх. Нічого про REST не гарантує, що воно є стійким. Ви можете зробити запит GET /jobs/37і отримати результат, тоді хтось видалить ресурс, і через 2 секунди той же запит поверне 404. Аналогічно, якщо ви POST /searchesі вас перенаправляєте на результат пошуку (пошук створено, і ви отримуєте 201 з Розташування заголовка до ресурсу), через 2 секунди цей результат може бути стертий з пам'яті та підлягає відновленню. Не потрібно тривалого зберігання.
stevendesu

5

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

Для кращого опису пошуку ми повинні говорити про архітектуру, зокрема, та, яка краще підходить, це ресурсно-орієнтована архітектура (ROA).

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

За визначенням, ресурс - це все, на що важливо посилатися як на річ сам по собі.

У архітектурі, орієнтованій на ресурси (давайте назвемо це ROA відтепер для стислості), ми зосередимось на ресурсі, який може бути багато речей:

  • Версія документа
  • Остання оновлена ​​версія документа
  • Результат пошуку
  • Список об’єктів
  • Перша стаття, яку я купив з електронної комерції

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

Таким чином, пошук ідеально вписується в RESTful з огляду на ROA . Ми повинні використовувати GET, оскільки я припускаю, що ваш пошук - це звичайний пошук, і він нічого не змінює, тому він ідентичний (навіть якщо він повертає різні речі залежно від доданих нових елементів). Тут виникає плутанина, тому що я можу дотримуватися RESTful, а не ROA, це означає, що я можу дотримуватися шаблону, який створює пошук і повертати різні речі з однаковими параметрами, тому що я не використовую принцип адресності ROA. Як у тому, що? Добре, якщо ви надсилаєте пошукові фільтри в тілі або заголовку, ресурс не АДРЕСАЛЬНИЙ.

Ви можете знайти принципи, що саме і URI, в оригінальному документі W3:

https://www.w3.org/DesignIssues/Axioms

Будь-яка URL-адреса в цій архітектурі повинна бути самоописовою. Це необхідно, якщо ви керуєтесь принципами, щоб вирішити все в URI, це означає, що ви можете використовувати / (косою рисою), щоб розділити все, що вам потрібно, або параметри запиту. Ми знаємо, що в цьому є обмеження, але це структура архітектури.

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

http://myapi.com/sum/1/2

Якщо суму, 1 і 2 можна змінити, але результат обчислення є унікальним і адресованим, кожен раз, коли я дзвоню з однаковими параметрами, отримую те саме, і нічого не змінюється в сервісі. Резюме / сума / 1/2 та / субстрат / 5/4 ідеально дотримується принципів.


3

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

Отримання GET повернення різних результатів для одного і того ж URI порушує idempotency / безпеку та принцип CoolURI і, отже, не є RESTful . Можна ідентичні дієслова записувати в базу даних, але вони ніколи не повинні впливати на представлення.

Загальний пошук починається із запиту POST, який повертає посилання на результат. Це генерує результат (він новий і може бути отриманий з наступним GET). Цей результат, звичайно, може бути ієрархічним (додаткові посилання на URI, які ви можете отримати), і, можливо, може повторно використовувати елементи попереднього пошуку, якщо це має сенс для програми.

До речі, я знаю, що люди роблять це по-різному. Не потрібно мені пояснювати, як зручно порушувати REST.


Аааааааа - так ТО, як це має працювати! Дякую!
Роб Бейлі

1
Idempotency не означає, що вона повинна завжди повертатися абсолютно однаково, вона повинна повертати те саме, якщо НІЧОГО не змінилося. Пошук можна вважати результатом обчислення, і це сам ресурс.
Максиміліано Ріос

Ідентифікація насправді НЕ означає, що результат залишається однаковим. Можна керувати кешем, і це практично можливо. І ви, звичайно, можете використовувати DELETE, що заважає пізнім GET. Якщо, однак, агенту потрібно зберігати знання про роботу програми, то це вже не ВІДБУДОВО. Вище я говорив про найекстремальнішу ідею REST. На практиці люди можуть порушувати багато аспектів цього. Вони платять ціну, коли кеші вже не кешують ефективно.
Мартін Суджоарто

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