Яке дієслово HTTP я повинен використовувати для запуску дії в веб-службі REST?


80

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

Ми почали з простого GETдо URI такого: ${path}/cache/reload(параметри не передаються, викликається лише URI). Мені відомо, що дані не слід змінювати за допомогою GET-запиту.

Яке правильне дієслово використовувати для виклику дії / команди в веб-службі RESTful?

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

Напевно, те, що я намагаюся зробити, це не REST, але це все-таки щось, що потрібно зробити так. reloadМетод був тільки реальний приклад того, що має сенс в рамках програми та більшість відповідей зосереджені на ньому, але насправді, мені просто потрібно знати , який дієслово , щоб викликати дію , яка не робить CRUD, але по- , як і раніше змінює дані / держава.

Я знайшов цю детальну інформацію про тему переповнення стека на тему: https://stackoverflow.com/questions/16877968/


1
"Перезавантаження" - це сенс програми, що оновлює дані, які збирається відображати? Чи є різниця між перезавантаженням та просто отриманням даних знову?
Шон Редмонд

1
@SeanRedmond Ні, дані не надсилаються клієнту. Фактично, це клієнт, який звертається до веб-сервісу REST, щоб виконати та внутрішнє командування (перезавантаження). Щось на зразок: "в базі даних було змінено багато конфігурацій, тому веб-сервіс REST, перезавантажте їх зараз у свою пам'ять".
Ренато Діньяні

Крос-сайт дубльовані: stackoverflow.com/q/15340946/319403
Chao

Чи планували ви використовувати параметр заголовка для відповідних запитів? Це дуже схоже на оновлення кешу ...
Гуран

Відповіді:


25

Я не думаю, що для цієї дії є правильне дієслово, оскільки ця транзакція насправді не є "RESTful". "S" і "t" означають "передачу стану", і тут нічого не передається. Або, кажучи іншим способом, за найсуворішим визначенням, такі дієслова, як PUT і POST, завжди використовуються з іменником, а «reload» - саме дієслово.

Це перезавантаження може бути не ВИПУСКОВИМ, але воно все ще може бути корисним, і вам просто доведеться вибрати спосіб це зробити і пожити з ним або пояснити, що це незвично. GET, мабуть, найпростіший. Однак у коментарях є досить скептицизм, тож варто подумати над тим, чи потрібно це перезавантаження, оскільки щось інше не зовсім робить те, що має робити.


Я погоджуюсь, що це не ВИПУСК, але може бути корисним. Я думаю, вам слід порадити PUT, оскільки це, ймовірно, безсильне, але не є нульовим.
Аарон Грінвальд

@Aaron, порівняння idempotent і nullimpotent - це все добре і добре, але як визначити, коли це несильно?
Крейг

@Craig - це ідентичне, якщо запустити його багато разів, має такий же ефект, як запустити його один раз. Це нікчемно, якщо запуск одного разу або багато разів має такий же ефект на сервері, як і запуск його в нуль разів. en.wikipedia.org/wiki/Idempotence
Аарон Грінвальд,

5
@AaronGreenwald "неімпотентний" [not-im-poht-nt] [not-im-pawr-tnt] - прикметник - 1. Гра на слова, "не важливо", антонім прикметника "важливо". 2. Гумор ... ;-)
Крейг

@Craig я повністю пропустив це :)
Аарон Грінвальд

75

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

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

Таким чином, клієнт виводить новий стан на сервер для цього ресурсу. Це може бути так само просто, як цей JSON

PUT http://myserver.com/services/email_service HTTP/1.1
Content-Type: text/json

{"status":"paused"}

Сервер визначає, як перейти від поточного стану (скажімо, "працює") до "призупиненого" стану / стану.

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

Причина зробити це таким чином, і чому REST може бути настільки потужним, полягає в тому, що ви залишаєте HOW, щоб дістатися до цього стану до сервера.

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

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


2
Що стосується мене, це правильна відповідь. Оновлення даних на сервері не є ідентичною операцією, і GETє абсолютно невідповідним дієсловом для використання. PUTє найбільш підходящим дієсловом, оскільки операція може вважатися оновленням "перезавантаженого стану" кешу до "перезавантаженого".
Їжак

@Jez З відповідей тут я вважаю за краще і цей. Вставляти з електронної метафорою, навскидку це дійсно відчуває дивне на першому думати відправки пошти, помістивши його в «відправки» держава замість того , щоб просто відправивши його (дія). Але якщо ви подумаєте про це, це дійсно те саме, що помістити його у «вихідну». Насправді, сама поштова система, ймовірно, стоїть у черзі її внутрішньо, коли ви скажете їй надіслати. Таким чином, API може дозволити вам перевести пошту в стан "відправлення", і API не зобов'язаний пояснювати себе поза цим.
Крейг

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

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

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

32

Деякі з інших відповідей, включаючи прийняту, радять використовувати GET (хоча і не дуже захоплено).

Я не погоджуюсь.

Перш за все, всі інші, які говорять вам, що це не ідеально і не дуже RESTful, є правильними. У правильному сценарії RESTful ви маніпулюєте ресурсами на сервері та додаєте, оновлюєте, видаляєте, отримуєте і т.д. ці ресурси. PUT повинен надіслати корисне навантаження, яке представляє, яким повинен бути ресурс, коли запит буде завершений, а POST повинен надіслати корисний вантаж, який представляє ресурс, який потрібно додати на сервер. І GET повинен повернути ресурс на сервері.

У вас є RPC (віддалений виклик процедури), який не є RESTful - ви хочете щось зробити на сервері. Тож якщо ви намагаєтесь створити чисто RESTful API, вам слід переглянути, що ви робите.

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

Якщо це зробити, я б рекомендував PUT або POST, залежно від того, чи є RPC ідентичним або ні.

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

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


6

POSTі PUTє дієсловами HTTP, які використовуються для подання сутності на веб-сервер. З PUT, представлена ​​сутність - це (нове) представлення ресурсу для даного URI, яке не відповідає бажаному. POSTпризначений для традиційного обробника форм, де сутність є допоміжними даними для ресурсу, тому це переможець. Суб'єкт повинен включати команду чи дію (наприклад, "action = reload").

При цьому, мабуть, не слід відкривати цю команду через інтерфейс REST. Це здається, що необхідність "перезавантажуватися" виникає через те, що дані можна змінювати через якийсь інший канал (наприклад, файлова система, клієнт DB). Схованки повинні бути прозорими. Крім того, HTTP-запити повинні бути атомними, навіть враховуючи повідомлення, що надсилаються по інших каналах. Запропонувати команду "перезавантажити" налаштування конфігурації здається непотрібною складністю; вимагає цього - крихкий дизайн. Піддавання "перезавантаження" очищенню після оновлення через інший канал брудне, оскільки один канал не містить усієї розмови. Замість цього розгляньте одне з:

  • вносити оновлення повністю через REST
  • виставляючи команди (и) на інший канал
  • автоматизація дій

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

Дивіться також " PUT vs POST in REST ".


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

@ RenatoDinhaniConceição: навіть без "внутрішнього" все одно пахне. Можливо, вам слід задати нове питання про те, чи хороший дизайн.
outis

4

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

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


Подивіться на мою редакцію. "reload" - це не команда, яка повертає дані. Це стосується самого веб-сервісу REST. Загалом, моє запитання стосується запуску дій у веб-службі REST. Інший приклад може бути: email_queue/stop_sending_emails. Я просто даю команду чимось за допомогою інтерфейсу RESTful.
Ренато Діньяні

5
Я все одно згоден. Викликати SIGHUP на локальний процес має сенс, оскільки комп'ютер повинен довіряти тому, хто ввійшов у локальну мережу, хто має доступ до цього сигналу. Але для протоколу без громадянства, доступного в Інтернеті? Можливо, веб-служба повинна автоматично перезавантажуватись за необхідності за допомогою опитування або моніторингу файлів. Цей дзвінок повинен бути абсолютно непотрібним.

1
Я згоден. Такі речі, як конфігурація та кешування, повинні бути прозорими для клієнта. Можливо, ви повинні дати нам більш конкретний опис ситуації, в якій буде названо вашу кінцеву точку.
Бенджамін Ходжсон

3

Чому б не ставитися до дії як до ресурсу. Отже, оскільки ви хочете оновити кеш, ви розмістите нову дію у вашій системі.

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

Загальна операція / дії / {action}

Операція, характерна для типу ресурсу / дії / {ресурс} / {дія}

Операція, характерна для ресурсу / дії / {ресурс} / {id} / {дія}

У вашому випадку кеш, ймовірно, загальносистемний / action / reload_cache


0

Яке дієслово HTTP я повинен використовувати для запуску дії в веб-службі REST?

Розглядаючи деталі послуги REST, часто корисно враховувати цю евристику: як би ви реалізували це за допомогою веб-сайту?

HTML може лише описувати GET та POST запити. Тож ми можемо почати пошук там.

Чи GETпідходить? Щоб відповісти на це запитання, нам потрібно подумати про припущення, які можуть робити клієнти та проміжні компоненти GET. Семантика безпеки GETє безпечною

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

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

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

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

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

PUT, PATCH, DELETE... ці небезпечні методи з більш конкретними семантики , ніж POST; чи підходять вони чи ні, залежатиме від вашої моделі ресурсів.

Важливою ідеєю, яку слід пам’ятати, є те, що методи HTTP належать до домену документа (див. Розмову Джима Вебера у 2011 р. ), Описані вами ефекти, ймовірно, не є частиною домену документа, а натомість побічні ефекти викликаються при зміні документів. . Це дає вам велику свободу з точки зору того, як ви організовуєте свої документи для роботи.

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