Как написать REST API на TypeScript за 30 минут: для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение

Современная веб-разработка немыслима без REST API. Это фундамент, на котором строятся мобильные приложения, SPA-фронтенды и микросервисы. Если вы новичок и хотите быстро освоить создание backend'а, то связка TypeScript + Express — идеальный старт. TypeScript добавляет строгую типизацию в JavaScript, что делает код надежнее и понятнее, особенно при работе в команде.

В этом руководстве мы за 30 минут создадим полноценный REST API для управления списком задач (Todo list). Вы научитесь настраивать проект, описывать модели данных, создавать маршруты и подключать базу данных. Никакой лишней теории — только практика и готовый к запуску код.

Предполагается, что у вас уже установлены Node.js (версия 18+) и npm. Если нет — скачайте их с официального сайта.

1. Подготовка проекта и установка зависимостей

Начнем с инициализации нового проекта TypeScript. Откройте терминал и выполните команды:

mkdir my-todo-api
cd my-todo-api
npm init -y

Теперь установим необходимые пакеты:

npm install express
npm install -D typescript @types/node @types/express ts-node nodemon

Создадим конфигурационный файл TypeScript:

npx tsc --init

В файле tsconfig.json убедитесь, что раскомментированы и настроены следующие строки:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Создайте папку src и файл src/index.ts — это будет точка входа нашего приложения.

Добавим скрипты в package.json для удобного запуска:

"scripts": {
  "dev": "nodemon --exec ts-node src/index.ts",
  "build": "tsc",
  "start": "node dist/index.js"
}

2. Создание базового сервера Express

Теперь напишем минимальный сервер на Express, который будет слушать порт 3000. Откройте src/index.ts и добавьте следующий код:

import express, { Request, Response } from 'express';

const app = express();
const PORT = 3000;

// Middleware для парсинга JSON
app.use(express.json());

// Базовый маршрут для проверки
app.get('/', (req: Request, res: Response) => {
  res.send('Todo API работает!');
});

app.listen(PORT, () => {
  console.log(`Сервер запущен на http://localhost:${PORT}`);
});

Запустите сервер командой npm run dev и откройте браузер по адресу http://localhost:3000. Вы должны увидеть сообщение "Todo API работает!".

3. Определение модели данных и in-memory хранилище

Для простоты мы не будем сразу подключать базу данных, а используем временное хранилище в оперативной памяти. Создайте файл src/models/todo.ts:

export interface Todo {
  id: number;
  title: string;
  completed: boolean;
  createdAt: Date;
}

export let todos: Todo[] = [
  { id: 1, title: 'Изучить TypeScript', completed: false, createdAt: new Date() },
  { id: 2, title: 'Написать REST API', completed: false, createdAt: new Date() },
];

Обратите внимание на использование интерфейса Todo — это гарантирует, что все объекты в массиве имеют одинаковую структуру.

4. Реализация CRUD-маршрутов

Создадим файл src/routes/todos.ts с полноценными маршрутами для операций Create, Read, Update и Delete.

import { Router, Request, Response } from 'express';
import { Todo, todos } from '../models/todo';

const router = Router();

// GET /api/todos — получить все задачи
router.get('/', (req: Request, res: Response) => {
  res.json(todos);
});

// GET /api/todos/:id — получить задачу по ID
router.get('/:id', (req: Request, res: Response) => {
  const id = parseInt(req.params.id);
  const todo = todos.find(t => t.id === id);
  if (!todo) {
    return res.status(404).json({ message: 'Задача не найдена' });
  }
  res.json(todo);
});

// POST /api/todos — создать новую задачу
router.post('/', (req: Request, res: Response) => {
  const { title } = req.body;
  if (!title || typeof title !== 'string') {
    return res.status(400).json({ message: 'Поле title обязательно' });
  }
  const newTodo: Todo = {
    id: todos.length > 0 ? Math.max(...todos.map(t => t.id)) + 1 : 1,
    title,
    completed: false,
    createdAt: new Date(),
  };
  todos.push(newTodo);
  res.status(201).json(newTodo);
});

// PUT /api/todos/:id — обновить задачу
router.put('/:id', (req: Request, res: Response) => {
  const id = parseInt(req.params.id);
  const todo = todos.find(t => t.id === id);
  if (!todo) {
    return res.status(404).json({ message: 'Задача не найдена' });
  }
  const { title, completed } = req.body;
  if (title !== undefined) todo.title = title;
  if (completed !== undefined) todo.completed = completed;
  res.json(todo);
});

// DELETE /api/todos/:id — удалить задачу
router.delete('/:id', (req: Request, res: Response) => {
  const id = parseInt(req.params.id);
  const index = todos.findIndex(t => t.id === id);
  if (index === -1) {
    return res.status(404).json({ message: 'Задача не найдена' });
  }
  todos.splice(index, 1);
  res.status(204).send();
});

export default router;

Теперь подключим маршруты в главном файле src/index.ts:

import todoRoutes from './routes/todos';
app.use('/api/todos', todoRoutes);

5. Тестирование API с помощью curl или Postman

Перезапустите сервер и протестируйте эндпоинты. Вот несколько примеров команд curl:

  • Получить все задачи: curl http://localhost:3000/api/todos
  • Создать новую задачу: curl -X POST -H "Content-Type:

Блоги

Рекомендаций по книгам