Как написать REST API на TypeScript за 30 минут

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

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

Начать курс

Как написать REST API на TypeScript за 30 минут: пошаговое руководство

Создание REST API — это базовая задача для любого backend-разработчика. Использование TypeScript добавляет строгую типизацию, улучшает читаемость кода и снижает количество ошибок. В этой статье мы разберем, как написать полноценный REST API на TypeScript с нуля всего за 30 минут. Вы познакомитесь с Express, TypeORM и лучшими практиками организации кода.

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

Первым делом создайте новую директорию и инициализируйте проект Node.js:

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

Установите необходимые пакеты:

npm install express reflect-metadata typeorm sqlite3
npm install -D typescript @types/node @types/express ts-node nodemon

Создайте файл tsconfig.json для конфигурации TypeScript:

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

2. Создание базовой структуры и точки входа

Организуйте структуру папок следующим образом:

  • src/ — основной код
  • src/controllers/ — контроллеры
  • src/entities/ — сущности базы данных
  • src/routes/ — маршруты

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

import "reflect-metadata";
import express from "express";
import { AppDataSource } from "./data-source";
import { userRoutes } from "./routes/userRoutes";

const app = express();
const PORT = process.env.PORT || 3000;

app.use(express.json());

AppDataSource.initialize()
  .then(() => {
    console.log("Database connected");
    app.use("/api/users", userRoutes);
    app.listen(PORT, () => {
      console.log(`Server running on http://localhost:${PORT}`);
    });
  })
  .catch((error) => console.log(error));

Теперь создайте src/data-source.ts для конфигурации TypeORM:

import { DataSource } from "typeorm";
import { User } from "./entities/User";

export const AppDataSource = new DataSource({
  type: "sqlite",
  database: "database.sqlite",
  synchronize: true,
  logging: false,
  entities: [User],
});

3. Определение сущности и контроллера

Создайте файл src/entities/User.ts — модель пользователя:

import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column()
  name!: string;

  @Column()
  email!: string;

  @Column({ default: true })
  isActive!: boolean;
}

Теперь создадим контроллер src/controllers/userController.ts:

import { Request, Response } from "express";
import { AppDataSource } from "../data-source";
import { User } from "../entities/User";

const userRepository = AppDataSource.getRepository(User);

export const getUsers = async (req: Request, res: Response) => {
  try {
    const users = await userRepository.find();
    res.json(users);
  } catch (error) {
    res.status(500).json({ message: "Error fetching users" });
  }
};

export const getUserById = async (req: Request, res: Response) => {
  try {
    const user = await userRepository.findOneBy({ id: parseInt(req.params.id) });
    if (!user) {
      return res.status(404).json({ message: "User not found" });
    }
    res.json(user);
  } catch (error) {
    res.status(500).json({ message: "Error fetching user" });
  }
};

export const createUser = async (req: Request, res: Response) => {
  try {
    const { name, email } = req.body;
    const user = userRepository.create({ name, email });
    const savedUser = await userRepository.save(user);
    res.status(201).json(savedUser);
  } catch (error) {
    res.status(400).json({ message: "Error creating user" });
  }
};

export const updateUser = async (req: Request, res: Response) => {
  try {
    const user = await userRepository.findOneBy({ id: parseInt(req.params.id) });
    if (!user) {
      return res.status(404).json({ message: "User not found" });
    }
    userRepository.merge(user, req.body);
    const updatedUser = await userRepository.save(user);
    res.json(updatedUser);
  } catch (error) {
    res.status(400).json({ message: "Error updating user" });
  }
};

export const deleteUser = async (req: Request, res: Response) => {
  try {
    const result = await userRepository.delete(req.params.id);
    if (result.affected === 0) {
      return res.status(404).json({ message: "User not found" });
    }
    res.json({ message: "User deleted successfully" });
  } catch (error) {
    res.status(500).json({ message: "Error deleting user" });
  }
};

4. Настройка маршрутов и запуск сервера

Создайте src/routes/userRoutes.ts:

import { Router } from "express";
import {
  getUsers,
  getUserById,
  createUser,
  updateUser,
  deleteUser,
} from "../controllers/userController";

const router = Router();

router.get("/", getUsers);
router.get("/:id", getUserById);
router.post("/", createUser);
router.put("/:id", updateUser);
router.delete("/:id", deleteUser);

export { router as userRoutes };

Добавьте скрипты в package.json:

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

Запустите сервер командой:

npm run dev

Теперь ваш REST API работает! Протестируйте его с помощью curl или Postman:

# Создать пользователя
curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Иван", "email": "ivan@example.com"}'

# Получить всех пользователей
curl http://localhost:3000/api/users

Заключение

За 30 минут вы создали полноценный REST API на TypeScript с использованием Express и TypeORM. Ваше приложение поддерживает CRUD-операции, использует SQLite для хранения данных и имеет четкую архитектуру, разделяющую контроллеры, маршруты

Блоги

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