Тело запроса: JSON, form-data, urlencoded, файлы

↑ 1.2 HTTP и REST для не-разработчиков · ← Предыдущая · → Следующая

Обязательно~5 мин чтенияУровень: junior

Зачем это аналитику и PM

Одни и те же поля «имя и файл» уезжают тремя разными упаковками. Пока формат не назван, разработчик экрана и разработчик сервера собирают два несовместимых запроса и спорят на приёмке.

План темы

  • чем отличаются форматы
  • как отправить файл
  • как выбрать в Postman

Объяснение

Тело запроса — полезная нагрузка сообщения, то, что не поместили в адрес и заголовки. Формат тела задаёт заголовок Content-Type. Расширение файла на диске аналитика само по себе сервер не убеждает.

Как посылка. JSON — один аккуратный свёрток с подписями на каждом предмете. Urlencoded — открытка, где поля дописаны в одну строку, почти как query. Form-data — коробка с перегородками: в одном отсеке текст, в другом файл. Перепутать открытку и коробку значит, что получатель не найдёт вложение, даже если «все поля были».

Чем форматы отличаются

JSON — текст из объектов, списков и значений. Им описывают заказ, профиль, фильтр, если он не влез в адрес. Имена полей чувствительны к регистру. Лишняя запятая ломает весь разбор: это уже 400, а не ошибка одного поля.

application/x-www-form-urlencoded — пары имя=значение, соединённые &, с процентным кодированием. Так устроены старые HTML-формы без файлов. Вложенный заказ из нескольких позиций здесь передавать неудобно: нет естественных объектов и списков.

multipart/form-data режет тело на части. У каждой части своё имя поля и свой кусок данных. Текст и файл едут вместе. Граница между частями — служебная строка, её ставит клиент. В требованиях её не выдумывают руками.

ФорматКогда уместенЧего не ждать
JSONКарточки, команды, вложенные поляВложения файла без отдельной договорённости
urlencodedПростая форма без файлаСписков и вложенных объектов
form-dataФайл плюс поля рядомЧто сервер сам угадает JSON внутри файла
Без телаЧтение, где всё уже в URLПолей «ещё и в теле на всякий случай»

GET с телом в постановку лучше не закладывать. Часть клиентов и промежуточных узлов тело у GET отбрасывает. Условия чтения кладут в query или переносят операцию на POST, если фильтр большой, и прямо пишут, что это чтение.

Файл и Postman

Файл — отдельная часть form-data: имя поля (attachment), имя файла и содержимое. Рядом в других частях едут orderId или комментарий. Ограничение размера, допустимые типы и что будет при повторе загрузки описывают в задаче. Фраза «приложите файл» не говорит, обновится старый файл или появится второй.

В Postman вид тела выбирают на вкладке Body. Для JSON обычно режим raw и указание JSON, для пар полей — x-www-form-urlencoded, для файла — form-data и тип File у нужной строки.

Примеры

JSON для создания. Это схема.

{
  "sku": "MUG-1",
  "qty": 2,
  "comment": "хрупкое"
}

Та же пара полей как urlencoded, без вложенности:

sku=MUG-1&qty=2&comment=%D1%85%D1%80%D1%83%D0%BF%D0%BA%D0%BE%D0%B5

Схема частей form-data. Это не сырой дамп с настоящей границей, а список того, что должно уехать.

part orderId = 1042
part comment = хрупкое
part attachment = file mug.png
Content-Type всего запроса: multipart/form-data

Живой POST на httpbin возвращает присланное тело эхом. Удобно проверить, что уехал JSON, а не форма. Состав ответа смотрите у сервиса, здесь только команда.

curl -sS -X POST "https://httpbin.org/post" -H "Content-Type: application/json" -d "{\"sku\":\"MUG-1\",\"qty\":2}"

Нюансы и подводные камни

  • Неверная запятая в JSON роняет весь запрос. В баге приложите тело как текст, не пересказ.
  • Число и строка "2" — разные значения JSON. В контракте тип назван явно.
  • Urlencoded не умеет файл. Если в сценарии есть вложение, это form-data или отдельный метод загрузки, не «та же форма».

Практика

Для сценария «создать заявку с одним вложением» выберите формат, перечислите поля и отметьте, которое является файлом.

Ожидаемый результат: назван multipart/form-data, у файла есть имя поля, у текстовых полей — типы. Рядом сказано, что JSON этого вложения не заменяет. Лимит размера либо указан командой, либо стоит вопрос, а не выдуманное число мегабайт.

Вопросы с ответами

Связано с блоком Developer

Связанные темы