Мені потрібно викликати процес, який не потребує вводу від користувача, а лише тригер. Я планую використовувати POST / uri без тіла для запуску процесу. Хочу знати, чи вважається це поганим з точки зору HTTP та REST?
Мені потрібно викликати процес, який не потребує вводу від користувача, а лише тригер. Я планую використовувати POST / uri без тіла для запуску процесу. Хочу знати, чи вважається це поганим з точки зору HTTP та REST?
Відповіді:
Я поставив це запитання робочій групі IETF HTTP кілька місяців тому. Коротка відповідь: ні, це не погана практика (але я пропоную прочитати нитку для отримання більш детальної інформації).
Використання POST замість GET є цілком розумним, оскільки воно також наказує серверу (і шлюзам по шляху) не повертати кешований відповідь.
POST повністю в порядку. На відміну від GET від POST ви змінюєте стан системи (швидше за все, ваш тригер "щось" робить і змінює дані).
Я вже використовував POST без корисного навантаження, і він "відчуває себе" добре. Одне, що вам слід зробити при використанні POST без корисного навантаження: Передати заголовок Content-Length: 0
. Я пам’ятаю проблеми з деякими проксі-серверами, коли api-клієнт не передавав це.
Якщо ви використовуєте POST / uri без тіла, це щось на зразок використання функції, яка не приймає аргумент .eg int post (void); тому розумно функціонувати до вашого класу ресурсів, який може змінити стан об'єкта без аргументу. Якщо ви вирішили реалізувати сенсорну функцію Unix для URI, чи це не вдалий вибір?
Так, нормально надсилати POST-запит без тіла та замість цього використовувати параметри рядка запиту. Але будьте обережні, якщо ваші параметри містять символи, недійсні для HTTP, вам доведеться їх кодувати.
Наприклад, якщо вам потрібно відправити "привіт світ" до кінцевої точки, вам доведеться зробити так, як це: http://api.com?param=hello%20world
Підтримка відповідей, що POST в цьому випадку нормальна, полягає в тому, що у випадку Python рамка OpenAPI "FastAPI" генерує графічний інтерфейс Swagger (див. Зображення), який не містить розділу Body, коли метод (див. Приклад нижче) мати параметр для прийняття тіла.
метод "post_disable_db" просто приймає параметр шляху "db_name" і не має 2-го параметра, який би передбачав обов'язковий орган.
@router.post('/{db_name}/disable',
status_code=HTTP_200_OK,
response_model=ResponseSuccess,
summary='',
description=''
)
async def post_disable_db(db_name: str):
try:
response: ResponseSuccess = Handlers.databases_handler.post_change_db_enabled_state(db_name, False)
except HTTPException as e:
raise (e)
except Exception as e:
logger.exception(f'Changing state of DB to enabled=False failed due to: {e.__repr__()}')
raise HTTPException(HTTP_500_INTERNAL_SERVER_ERROR, detail=e.__repr__())
return response