Использовали ли вы REST API в Node.js проектах?

«Использовали ли вы REST API в Node.js проектах?» — вопрос из категории Сети, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, разрабатывал RESTful API на Node.js для множества проектов, используя Express.js и следуя общепринятым best practices.

Пример структуры REST API, которую я реализовывал:

// routes/users.js
const express = require('express');
const router = express.Router();
const UserController = require('../controllers/userController');
const { validateUser } = require('../middleware/validation');

// GET /api/v1/users - Получить список пользователей с пагинацией
router.get('/', UserController.getAllUsers);

// GET /api/v1/users/:id - Получить конкретного пользователя
router.get('/:id', UserController.getUserById);

// POST /api/v1/users - Создать нового пользователя
router.post('/', validateUser, UserController.createUser);

// PUT /api/v1/users/:id - Полное обновление пользователя
router.put('/:id', validateUser, UserController.updateUser);

// PATCH /api/v1/users/:id - Частичное обновление
router.patch('/:id', UserController.partialUpdateUser);

// DELETE /api/v1/users/:id - Удалить пользователя
router.delete('/:id', UserController.deleteUser);

module.exports = router;

Ключевые принципы, которые я соблюдал:

  1. Использование правильных HTTP методов:

    • GET для получения данных
    • POST для создания
    • PUT/PATCH для обновления
    • DELETE для удаления
  2. Семантические статус-коды:

    // В контроллере
    const getUserById = async (req, res) => {
    try {
    const user = await User.findById(req.params.id);
    if (!user) {
      return res.status(404).json({ error: 'User not found' });
    }
    res.status(200).json(user);
    } catch (error) {
    res.status(500).json({ error: 'Internal server error' });
    }
    };
  3. Версионирование API: Всегда использовал префикс /api/v1/ для возможности обратно совместимых изменений

  4. Пагинация, фильтрация, сортировка:

    // GET /api/v1/users?page=1&limit=20&sort=-createdAt&status=active
    const getAllUsers = async (req, res) => {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 20;
    const skip = (page - 1) * limit;
    
    const filter = {};
    if (req.query.status) filter.status = req.query.status;
    
    const sort = {};
    if (req.query.sort) {
    const sortField = req.query.sort.startsWith('-') ? req.query.sort.substring(1) : req.query.sort;
    sort[sortField] = req.query.sort.startsWith('-') ? -1 : 1;
    }
    
    const users = await User.find(filter)
    .sort(sort)
    .skip(skip)
    .limit(limit);
    
    const total = await User.countDocuments(filter);
    
    res.json({
    data: users,
    pagination: { page, limit, total, pages: Math.ceil(total / limit) }
    });
    };
  5. REST для вложенных ресурсов:

    • GET /api/v1/users/:userId/posts - Получить посты пользователя
    • POST /api/v1/users/:userId/posts - Создать пост для пользователя

Также интегрировал REST API с внешними сервисами (платежные системы, email-сервисы) используя axios с retry logic и circuit breaker.