Back

Создание вашего первого API с Koa

Создание вашего первого API с Koa

Если вы знаете JavaScript и хотите создать backend API, Koa заслуживает серьёзного внимания. Этот фреймворк минималистичен, современен и изначально построен на основе async/await — что означает более чистый код и отсутствие «ада колбэков». Данное руководство по Koa API проведёт вас через основы: настройку проекта, понимание работы middleware и создание небольшого REST API с GET и POST эндпоинтами.

Ключевые моменты

  • Koa — это лёгкий Node.js фреймворк без встроенного middleware — вы компонуете только то, что вам нужно.
  • Его каскадная модель middleware по принципу «луковицы» позволяет каждой функции выполнять логику как до, так и после последующих обработчиков.
  • Объект ctx объединяет данные запроса и ответа, делая обработчики маршрутов чистыми и читаемыми.
  • С помощью @koa/router и @koa/bodyparser вы можете развернуть рабочий REST API в одном файле.

Предварительные требования

  • Node.js 20+ (рекомендуется текущая LTS-версия)
  • Базовые знания JavaScript, включая async/await
  • Терминал и текстовый редактор

Что такое Koa и зачем его использовать?

Koa — это лёгкий веб-фреймворк для Node.js, созданный командой разработчиков Express. В отличие от Express, Koa не имеет встроенного middleware — вы добавляете только то, что необходимо. Его отличительная особенность — каскад middleware, иногда называемый «луковичной моделью», где каждая middleware-функция выполняет код до и после следующей в цепочке.

Это делает основы API Koa простыми для понимания: каждый запрос проходит внутрь через стек middleware, а ответ возвращается обратно наружу.

Шаг 1 — Настройка проекта

Создайте новую директорию и инициализируйте её:

mkdir koa-items-api && cd koa-items-api
npm init -y

Добавьте "type": "module" в package.json для использования синтаксиса ES-модулей, затем установите зависимости:

npm install koa @koa/router @koa/bodyparser
  • koa — ядро фреймворка
  • @koa/router — официальный middleware для маршрутизации
  • @koa/bodyparser — парсит входящие JSON-тела запросов

Шаг 2 — Понимание API middleware в Koa

Каждый middleware в Koa — это async-функция, которая получает объект ctx (контекст) и функцию next. Объект ctx объединяет запрос и ответ в одном месте — ctx.method, ctx.path, ctx.request.body и ctx.body (ответ) находятся там.

Вызов await next() передаёт управление следующему middleware. Вот простой пример логирования:

app.use(async (ctx, next) => {
  const start = Date.now()
  await next()
  console.log(`${ctx.method} ${ctx.path} — ${Date.now() - start}ms`)
})

Обратите внимание, что код после await next() выполняется после завершения работы последующего middleware. Это луковичная модель в действии.

Шаг 3 — Создание REST API с Koa

Создайте файл app.js с небольшим API для работы с элементами в памяти:

import Koa from "koa"
import Router from "@koa/router"
import  bodyParser  from  "@koa/bodyparser"

const app = new Koa()
const router = new Router()

// Хранилище данных в памяти
let nextId = 3
let items = [
  { id: 1, name: "Keyboard" },
  { id: 2, name: "Monitor" },
]

// GET /items — вернуть все элементы
router.get("/items", (ctx) => {
  ctx.body = { success: true, data: items }
})

// GET /items/:id — вернуть один элемент
router.get("/items/:id", (ctx) => {
  const item = items.find((i) => i.id === Number(ctx.params.id))
  if (!item) {
    ctx.status = 404
    ctx.body = { error: "Item not found" }
    return
  }
  ctx.body = { success: true, data: item }
})

// POST /items — создать новый элемент
router.post("/items", (ctx) => {
  const { name } = ctx.request.body
  if (!name) {
    ctx.status = 400
    ctx.body = { error: "Name is required" }
    return
  }
  const newItem = { id: nextId++, name }
  items.push(newItem)
  ctx.status = 201
  ctx.body = { success: true, data: newItem }
})

app.use(bodyParser())
app.use(router.routes())
app.use(router.allowedMethods())

app.listen(3000, () => console.log("Server running on http://localhost:3000"))

Примечание: Исходный подход id: items.length + 1 ломается, если вы когда-либо удаляете элемент, потому что длина массива уменьшается, а существующие ID — нет. Отдельный счётчик nextId позволяет избежать дублирования ID.

Запустите сервер:

node app.js

Тестирование эндпоинтов

Получить все элементы:

curl http://localhost:3000/items

Создать элемент:

curl -X POST http://localhost:3000/items \
  -H "Content-Type: application/json" \
  -d '{"name": "Mouse"}'

Ожидаемый ответ:

{ "success": true, "data": { "id": 3, "name": "Mouse" } }

Запросить несуществующий элемент:

curl http://localhost:3000/items/99
{ "error": "Item not found" }

Метод router.allowedMethods() автоматически обрабатывает неподдерживаемые HTTP-методы, возвращая корректный ответ 405 Method Not Allowed без дополнительного кода.

Заключение

Сила Koa — в его простоте. Объект ctx держит обработку запроса и ответа в одном месте, а каскад middleware даёт вам точный контроль над тем, как запросы проходят через ваше приложение. Этого фундамента — сервер Koa, @koa/router для маршрутизации и @koa/bodyparser для парсинга JSON — достаточно, чтобы начать создавать REST API с Koa. Отсюда вы можете добавлять реальную базу данных, валидацию или middleware для обработки ошибок по одному слою за раз.

Часто задаваемые вопросы

Koa поставляется без встроенного middleware, поэтому вы устанавливаете только то, что нужно вашему проекту. Он также изначально использует async/await вместо колбэков, что упрощает обработку ошибок и управление потоком выполнения. Express полагается на традиционную сигнатуру middleware на основе колбэков, в то время как луковичная модель Koa позволяет каждому middleware выполнять логику как до, так и после последующих обработчиков.

Да. Koa стабилен, хорошо поддерживается и используется в production многими командами. Поскольку он минималистичен по дизайну, вы сами выбираете роутер, парсер тела запроса и слои обработки ошибок. Это даёт вам полный контроль над стеком зависимостей и сохраняет небольшой размер фреймворка, что может упростить аудит и долгосрочную поддержку.

Разместите middleware с try/catch в верхней части стека middleware. Поскольку Koa использует async/await, любая ошибка, выброшенная ниже по цепочке, всплывёт до этого внешнего обработчика. Затем вы можете установить ctx.status и ctx.body для возврата единообразного ответа об ошибке. Этот единственный middleware заменяет необходимость повторяющихся проверок ошибок в каждом маршруте.

Да. Koa и его официальные пакеты, такие как @koa/router и @koa/bodyparser, включают определения типов TypeScript. Вы можете настроить стандартный TypeScript-проект с ts-node или шагом сборки, импортировать Koa как обычно и получить полную типобезопасность для объекта ctx, параметров маршрута и тел запросов.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay