Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Тело запроса

Тело запроса — данные, которые клиент отправляет вместе с POST, PUT или PATCH: новую статью, комментарий, файл. Hono читает тело асинхронно, поэтому обработчик объявляют с async и пишут await.

JSON

API обычно принимает JSON. Добавьте маршрут создания статьи в src/index.ts:

// src/index.ts
app.post('/posts', async (c) => {
  const data = await c.req.json()
  return c.json({ received: data }, 201)
})

Отправьте запрос из терминала:

curl -X POST http://localhost:3000/posts \
  -H "Content-Type: application/json" \
  -d '{"title": "Новая статья", "body": "Текст"}'

Сервер вернёт отправленный объект внутри поля received и код 201.

Сохранение статьи

Теперь добавим статью в массив posts:

// src/index.ts
type NewPost = { title: string; body: string }
 
app.post('/posts', async (c) => {
  const data = await c.req.json<NewPost>()
  const post = { id: posts.length + 1, title: data.title, body: data.body }
  posts.push(post)
  return c.json(post, 201)
})

Обобщённый тип в c.req.json<NewPost>() только подсказывает TypeScript, какие поля ожидаются. Он ничего не проверяет: клиент может прислать что угодно. Настоящую проверку добавит урок о zod. После запроса GET /posts покажет уже три статьи — до перезапуска сервера, ведь массив живёт в памяти.

Данные формы

HTML-форма отправляет данные не в JSON, а в формате application/x-www-form-urlencoded или multipart/form-data. Для обоих случаев есть c.req.parseBody():

// src/index.ts
app.post('/comments', async (c) => {
  const body = await c.req.parseBody()
  const author = String(body.author ?? '')
  const text = String(body.text ?? '')
  return c.text(`${author} пишет: ${text}`)
})

Проверить можно так:

curl -X POST http://localhost:3000/comments -d "author=Anna" -d "text=Отличная статья"

Ответ — «Anna пишет: Отличная статья». Значение поля в parseBody() — строка или объект File, если форма загружала файл.

Другие способы

МетодКогда использовать
c.req.json()тело в формате JSON
c.req.parseBody()обычная HTML-форма
c.req.formData()нужен стандартный объект FormData
c.req.text()тело как строка
c.req.arrayBuffer()двоичные данные
// src/index.ts
app.post('/upload', async (c) => {
  const form = await c.req.formData()
  const file = form.get('cover')
  return c.text(file instanceof File ? `Файл ${file.name}` : 'Файла нет')
})

formData() возвращает тот же FormData, что и в браузере, с методами get() и getAll().

Частая ошибка

В теле приходит неверный JSON: одинарные кавычки вместо двойных, лишняя запятая, обрезанная строка. c.req.json() в таком случае выбрасывает ошибку разбора, и клиент получает код 500, хотя виноват он сам. Не доверяйте телу запроса: валидатор zod из следующей главы отвечает на неверные данные кодом 400, а урок об ошибках показывает, как оформить ответ.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.