Ответ
Да, разрабатывал 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;
Ключевые принципы, которые я соблюдал:
-
Использование правильных HTTP методов:
GETдля получения данныхPOSTдля созданияPUT/PATCHдля обновленияDELETEдля удаления
-
Семантические статус-коды:
// В контроллере 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' }); } }; -
Версионирование API: Всегда использовал префикс
/api/v1/для возможности обратно совместимых изменений -
Пагинация, фильтрация, сортировка:
// 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) } }); }; -
REST для вложенных ресурсов:
GET /api/v1/users/:userId/posts- Получить посты пользователяPOST /api/v1/users/:userId/posts- Создать пост для пользователя
Также интегрировал REST API с внешними сервисами (платежные системы, email-сервисы) используя axios с retry logic и circuit breaker.