3.1 Проектирование и реализация REST API (GET, POST, PUT, DELETE)
9 из 9 шагов пройдено
3 из 3 баллов  получено

POST-запросы

Продолжим разработку нашего проекта, пришло время реализовать функционал для принятия POST запросов, с помощью которого мы будем добавлять записи в нашу БД(словарь).

Использование метода GET для взаимодействия между клиентом и сервером через HTTP имеет определенные недостатки. Прежде всего, это не очень безопасно, так как URL-адрес вместе с данными параметров виден в адресной строке браузера. Во-вторых, существует ограничение на то, сколько данных может быть отправлено на сервер вместе с запросом GET.

Кроме того, отправляемые данные должны быть представлены только символами ASCII. Это означает, что любые двоичные данные, такие как изображение, не могут быть частью запроса GET. Чтобы отправить запрос на создание новой записи, протокол HTTP требует использования метода POST. И данные, необходимые для создания новой записи, упаковываются в тело запроса POST.

И у этого есть несколько преимуществ, часть тела запроса не отображается в адресной строке браузера, следовательно, это более безопасный метод. Во-вторых, нет ограничения по размеру, и необработанные двоичные данные также могут быть частью тела HTTP запроса.

В скелете нашего API нас уже есть функция, которая принимает POST запросы, принимая только сам текст записи. Метод мы объявили с помощью декоратора @app.post, посмотрим на наш скелет кода:

@app.post("/message")
async def create_message(message: str) -> str:
    return message

Обговорим какой функционал нам необходимо реализовать. Первым делом нам нужно получать id (что-то вроде автоинкремента по аналогии с БД) и записывать в наш словарь текст полученный из POST запроса. Также при успешном создании записи, нам нужно установить необходимый код ответа. Коды ответа — это уникальные короткие коды, выдаваемые сервером в ответ на запрос клиента. Коды состояния ответа сгруппированы в пять категорий, каждая из которых обозначает отдельный ответ:

  • 1XX: Запрос получен.
  • 2XX: Запрос выполнен успешно.
  • 3XX: Запрос перенаправлен.
  • 4XX: Ошибка клиента.
  • 5XX: Ошибка сервера.

Полный список кодов состояния HTTP можно найти по адресу https://www.webfx.com/web-development/glossary/http-status-codes/

Из текста выше видим что декоратор post принимает значение status_code. В нашем случае нам необходимо установить код 201, означающий успешное создание. Все статус коды в FastAPI мы можем посмотреть в документации.

Напишем весь этот код, первым делом импортируя модуль status из библиотеки fastapi.:

from fastapi import FastAPI, status


@app.post("/message", status_code=status.HTTP_201_CREATED)
async def create_message(message: str) -> str:
    current_index = len(messages_db)
    messages_db[current_index] = message
    return f"Message created!"

Запустим приложение через команду  uvicorn crud:app --port 8000 --reload и проверим работу. Зайдем в документацию, и попробуем отправить POST запрос:

 После заполнения поля message и нажатия на кнопку Execute мы получим следующий результат:

Мы получили код ответа 201, что говорит нам об успешном добавлении записи. Но как мы видим в скриншоте выше, наш текст в POST запросе был отправлен не в теле запроса, что видно в следующей команде curl:

curl -X 'POST' \
  'http://127.0.0.1:8000/message?message=Second%20post%20in%20FastAPI' \
  -H 'accept: application/json' \
  -d ''

И, следовательно, все содержимое запроса видно в URL строке. Чтобы упаковать параметр в тело запроса, нам необходимо познакомиться с классом Body

 

Body

Для получения данных из тела запроса можно использовать класс Body из пакета fastapi. Данный класс позволяет связать с параметром функции-обработчика запроса либо все тело запроса, либо какие-то отдельные его значения. Изменим нашу функцию:

from fastapi import FastAPI, status, Body


@app.post("/message", status_code=status.HTTP_201_CREATED)
async def create_message(message: str = Body()) -> str:
    current_index = len(messages_db)
    messages_db[current_index] = message
    return f"Message created!"

Запустим приложение. Мы видим что поля с параметрами запросов у нас теперь нет, и документация предлагает передать информацию внутри тела запроса. Попробуем добавить запись:

После нажатия кнопки отправки запроса, мы видим что наше сообщение находится внутри тела запроса:

Что подтверждает команда curl:

curl -X 'POST' \
  'http://127.0.0.1:8000/message' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '"Second post in FastAPI"'

Теперь наш текст был отправлен внутри POST запроса по адресу http://127.0.0.1:8000/message. И в конце мы можем отправить GET запрос, на получение всех записей:

Мы видим что теперь, в нашей БД в виде словаря, находится уже 2 записи. Одну из которых мы отправили с помощью POST запроса. В следующем шаге мы научимся изменять наши записи, выполняя PUT запрос.


Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Нет обсуждений. Начните первое.