24 KiB
Разрабатываем первое Web API на Node.js
Для секции "Веб-разработка: пример Fullstack"
Введение
Урок предназачен для аудитории, имеющей базовые навыки работы с HTML/CSS, Git и SSH. Цель: освоить основы разработки Web API с использованием Node.js и фреймворка Express за ограниченное время (3 часа).
Рекомендую очень хороший ресурс с теорией и практикой по Node.js
📘 Урок 1: Создание репозитория и организации структуры проекта
Цель урока: Создать GitHub-репозиторий, организовать структуру проекта и научиться работать с ветками в Git.
Краткая теория:
- GitHub — платформа для хостинга и совместной разработки IT-проектов с использованием системы контроля версий Git.
- Репозиторий — хранилище кода и истории его изменений.
- Ветка (branch) — изолированная копия проекта для разработки новой функциональности без влияния на основной код (часто называется
mainилиmaster).
Практические шаги:
-
Создайте репозиторий на GitHub:
- Авторизуйтесь на GitHub.
- Нажмите
+в правом верхнем углу и выберитеNew repository. - В поле
Repository nameукажите название, отражающее тему вашего API (например,my-first-api). - Оставьте репозиторий публичным (
Public). - Поставьте галочку
Add a README.md. Это создаст начальный файл описания проекта. - Нажмите
Create repository.
-
Клонируйте репозиторий и создайте учебную ветку:
# Склонируйте репозиторий на компьютер git clone git@github.com:<ваш-логин>/<название-репозитория>.git cd <название-репозитория> # Создайте и переключитесь на новую ветку 'study' git checkout -b study # Если в команде двое, каждый создает свою ветку (например, study-ivanov) # git checkout -b study-фамилия
Что должно получиться:
- Создан удаленный репозиторий на GitHub с файлом
README.md. - На вашем компьютере есть локальная копия проекта.
- Вы находитесь в новой ветке (
studyилиstudy-фамилия), а не в основной (main).
📦 Урок 2: Инициализация проекта Node.js
Цель урока: Создать структуру папок для backend и инициализировать проект Node.js.
Краткая теория:
- Node.js — это среда выполнения JavaScript вне браузера, которая позволяет создавать серверные приложения.
- package.json — это файл манифеста проекта Node.js, который содержит его описание, версию, список зависимостей и скриптов.
Практические шаги:
- Создайте папку
backendи перейдите в неё:mkdir backend cd backend - Инициализируйте проект Node.js. Используйте флаг
-y, чтобы принять значения по умолчанию, и--type=moduleдля поддержки современного синтаксиса ES-модулей:npm init -y --type=module
Проверка результата:
Убедитесь, что в папке backend появился файл package.json. В его первой строке должно быть указано "type": "module".
🚀 Урок 3: Установка фреймворка Express
Цель урока: Установить библиотеку Express — популярный фреймворк для создания веб-приложений и API на Node.js.
Краткая теория:
- Express — это минималистичный и гибкий фреймворк, который значительно упрощает создание серверных приложений и маршрутов.
- Зависимости (dependencies) — это сторонние библиотеки (пакеты), которые использует ваш проект. Они управляются с помощью
npm(Node Package Manager).
Практические шаги:
В папке backend выполните команду установки:
npm install express
Что должно получиться:
- В файле
package.jsonв раздел"dependencies"добавится"express"с номером версии. - В проекте появится папка
node_modules, где хранятся все установленные библиотеки.
🗑️ Урок 4: Работа с .gitignore и первый коммит
Atlassian: Файл .gitignore — игнорирование файлов в Git
Цель урока: Научиться игнорировать ненужные для репозитория файлы и зафиксировать изменения.
Краткая теория:
node_modules— это папка со всеми зависимостями проекта. Её нельзя добавлять в Git, так как она очень большая и её можно восстановить командойnpm install..gitignore— специальный файл, в котором перечисляются шаблоны файлов и папок, которые Git должен игнорировать.
Практические шаги:
- Создайте файл
.gitignoreв корне вашего проекта (на одном уровне с папкойbackend). - Добавьте в него шаблоны. Вы можете создать базовое содержимое на сайте gitignore.io. Введите
Node, Windows, VisualStudioCodeи скопируйте сгенерированный текст в ваш файл. - Убедитесь, что в
.gitignoreесть строки:node_modules/ .env - Выполните коммит:
# Вернитесь в корень проекта (если вы в папке backend) cd .. # Добавьте все новые файлы в staging area git add . # Зафиксируйте изменения с комментарием git commit -m "feat: инициализирован проект Node.js с Express, добавлен .gitignore"
📄 Урок 5: Создание базовой структуры сервера
Цель урока: Создать основные файлы приложения и понять их роль.
Краткая теория:
Серверное приложение на Express обычно разделяют на несколько файлов для лучшей организации:
server.js— точка входа. Запускает сервер, подключает основные настройки.app.js— ядро приложения. Содержит настройки Express и все маршруты (routes).
Практические шаги:
- В папке
backendсоздайте папкуsrc. - Внутри
srcсоздайте два файла:app.jsиserver.js. - В файл
app.jsпока добавьте только создание экземпляра приложения:// backend/src/app.js import express from 'express'; const app = express(); export default app; // Экспортируем app для использования в server.js - В файл
server.jsдобавьте код запуска сервера:// backend/src/server.js import app from './app.js'; const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Сервер запущен и слушает порт ${PORT}`); });
Что должно получиться:
Создана модульная структура приложения. Пока при запуске сервер будет работать, но на любой запрос возвращать ошибку 404, так как маршруты не определены.
▶️ Урок 6: Первый запуск сервера
Цель урока: Запустить сервер и убедиться, что он работает, возвращая ожидаемую ошибку.
Практические шаги:
- Из папки
backendвыполните команду:node src/server.js - В консоли должно появиться сообщение:
Сервер запущен и слушает порт 3000. - Откройте браузер и перейдите по адресу
http://localhost:3000. - Вы должны увидеть стандартную страницу ошибки
Cannot GET /. Это ожидаемо, так как мы не создали обработчик для корневого маршрута (/). - Остановите сервер, нажав
Ctrl + Cв терминале. - Выполните коммит:
git add . git commit -m "feat: создана базовая структура сервера, успешный запуск" git push origin study # Или study-фамилия
🖐️ Урок 7: Создание первого маршрута (Hello World)
Цель урока: Создать простейший обработчик GET-запроса и получить ответ от сервера.
Краткая теория:
- Маршрут (route) — это правило, которое определяет, как сервер будет реагировать на клиентский запрос к определенному URL (конечной точке) и HTTP-методу (GET, POST и т.д.).
- Обработчик (handler) — функция, которая принимает запрос (
req) и формирует ответ (res).
Практические шаги:
- Откройте файл
backend/src/app.js. - Добавьте обработчик для корневого маршрута (
/) перед строкойexport default app;:// Обработчик GET-запроса на корневой URL '/' app.get('/', (req, res) => { // Устанавливаем заголовок ответа res.setHeader('Content-Type', 'text/plain'); // Отправляем текстовый ответ res.send('Hello World from my API!'); }); - Запустите сервер снова (
node src/server.js) и обновите страницуhttp://localhost:3000в браузере. - Вы должны увидеть надпись
Hello World from my API!. - Выполните коммит.
🔢 Урок 8: Работа с параметрами пути (Path Parameters)
- Expressjs: Маршрутизация в Express
- Nodejsdev: Как построить REST API с помощью JS, Node.js и Express.js
Цель урока: Научиться создавать динамические маршруты и извлекать данные из URL.
Краткая теория:
- Статические маршруты — это фиксированные адреса, например,
/aboutили/contacts. Они всегда одинаковы. - Динамические маршруты — это адреса, которые могут меняться. Например, страница профиля с разными именами пользователей:
/user/anna,/user/max. - Параметры пути (Path Parameters) — специальные части URL, которые меняются. В Express они обозначаются двоеточием (
:), например:/user/:username. - Когда кто-то заходит на
/user/anna, Express видит:usernameв маршруте и понимает: "вместо:usernameподставленоanna". Это значение сохраняется вreq.params.
Примеры разных параметров:
- Один параметр:
// Когда заходят на /hello/Максим
app.get('/hello/:name', (req, res) => {
const name = req.params.name; // = "Максим"
res.send(`Привет, ${name}!`);
});
- Несколько параметров:
// Когда заходят на /book/сказки/5
app.get('/book/:genre/:page', (req, res) => {
const genre = req.params.genre; // = "сказки"
const page = req.params.page; // = "5"
res.send(`Жанр: ${genre}, Страница: ${page}`);
});
- Параметр в середине пути:
// Когда заходят на /category/электроника/product/123
app.get('/category/:categoryName/product/:productId', (req, res) => {
const category = req.params.categoryName; // = "электроника"
const productId = req.params.productId; // = "123"
res.send(`Категория: ${category}, Товар: ${productId}`);
});
Практические шаги:
- В файле
app.jsдобавьте маршрут:
// Пример запроса: GET http://localhost:3000/double/7
app.get('/double/:number', (req, res) => {
const input = req.params.number; // Получаем параметр из URL
// Проверяем, является ли параметр числом
if (!isNaN(input)) {
const number = parseFloat(input);
const result = number * 2;
res.send(`Если удвоить ${number}, получится ${result}`);
} else {
res.status(400).send('Пожалуйста, укажите число. Например: /double/10');
}
});
- Протестируйте:
http://localhost:3000/double/7→ работаетhttp://localhost:3000/double/abc→ ошибка
➕➖✖️➗ Урок 9: Практическое задание — Текстовый API-калькулятор
Цель задания: Создать простой калькулятор, который принимает числа в URL и возвращает текстовый результат.
Задание:
Создайте 4 маршрута для основных математических операций. Формат ответа — обычный текст.
Маршруты и примеры:
-
Сложение:
GET /api/calc/sum/:a/:b- Пример:
GET /api/calc/sum/5/3 - Ответ:
5 + 3 = 8
- Пример:
-
Вычитание:
GET /api/calc/subtract/:a/:b- Пример:
GET /api/calc/subtract/10/4 - Ответ:
10 - 4 = 6
- Пример:
-
Умножение:
GET /api/calc/multiply/:a/:b- Пример:
GET /api/calc/multiply/7/2 - Ответ:
7 * 2 = 14
- Пример:
-
Деление:
GET /api/calc/divide/:a/:b- Пример:
GET /api/calc/divide/15/3 - Ответ:
15 / 3 = 5
- Пример:
Как это сделать:
- Для каждого маршрута получите параметры из
req.params.aиreq.params.b - Преобразуйте их в числа:
const num1 = parseFloat(req.params.a) - Выполните операцию
- Верните ответ в формате:
res.send(`${num1} + ${num2} = ${result}`)
Важно:
- Пока не нужно проверять, корректные ли данные прислал пользователь
- Используйте шаблонные строки (обратные кавычки) для формирования ответа
⚠️ Урок 10: Базовые проверки в калькуляторе
Цель урока: Добавить минимальную проверку входных данных.
Задание:
Доработайте калькулятор из урока 9, добавив две простые проверки:
- Проверка, что оба параметра — числа
- Для деления — проверка, что второй параметр не ноль
Как это сделать:
Шаг 1: Проверка на число В начале каждого обработчика добавьте:
const a = parseFloat(req.params.a);
const b = parseFloat(req.params.b);
// Проверяем, являются ли оба параметра числами
if (isNaN(a) || isNaN(b)) {
return res.status(400).send('Ошибка: оба параметра должны быть числами');
}
Шаг 2: Проверка деления на ноль Только в обработчике деления добавьте после проверки на числа:
// Проверка деления на ноль
if (b === 0) {
return res.status(400).send('Ошибка: на ноль делить нельзя');
}
Что должно происходить:
/api/calc/sum/5/3→5 + 3 = 8(работает)/api/calc/sum/5/abc→Ошибка: оба параметра должны быть числами(ошибка 400)/api/calc/divide/10/0→Ошибка: на ноль делить нельзя(ошибка 400)
📊 Урок 11: Введение в формат JSON
Цель урока: Понять, что такое JSON и научиться отправлять данные в этом формате.
Краткая теория:
- JSON (JavaScript Object Notation) — популярный формат для обмена данными;
- у JSON есть строгий набор правил:
- Все ключи в двойных кавычках
- Значения: строки (в кавычках), числа, true/false, null, массивы [], объекты {}
- Пример JSON:
{
"имя": "Иван",
"возраст": 16,
"хобби": ["программирование", "шахматы"],
"студент": true
}
Практическое задание:
- Создайте маршрут
GET /api/user/:id - Если
:id— число, верните JSON с информацией о пользователе:
app.get('/api/user/:id', (req, res) => {
const id = req.params.id;
if (!isNaN(id)) {
// Формируем вручную объект пользователя.
// Пока что просто притворимся, что мы загрузили его из базы данных.
const userData = {
userId: Number(id),
name: "Алексей Петров",
email: "alexey@example.com",
registered: true
};
// Отправляем как JSON
res.json(userData);
} else {
// Если id не число - ошибка в JSON формате
res.status(400).json({
error: "ID должен быть числом",
example: "/api/user/123"
});
}
});
- Протестируйте в браузере:
http://localhost:3000/api/user/123→ увидите красиво оформленный JSONhttp://localhost:3000/api/user/abc→ JSON с ошибкой
Обратите внимание
В примере мы возвращаем фальшивые данные. С настоящими динамическими данными (списки/объекты БД) мы поработаем позже.
🔄 Урок 12: Калькулятор с JSON-ответами
Цель урока: Переделать текстовый калькулятор для возврата JSON.
Задание:
Измените все 4 операции калькулятора так, чтобы они возвращали данные в JSON-формате.
Формат успешного ответа:
{
"success": true,
"operation": "sum",
"arguments": {
"a": 5,
"b": 3
},
"result": 8
}
Формат ответа с ошибкой:
{
"success": false,
"error": {
"code": "DIVISION_BY_ZERO",
"message": "Делитель не может быть равен нулю"
}
}
Как изменить код:
- Заменяем
res.send()наres.json() - Для успешного ответа формируем объект:
const response = {
success: true,
operation: "sum", // или "subtract", "multiply", "divide"
arguments: {
a: a,
b: b
},
result: a + b // здесь ваша операция
};
res.json(response);
- Для ошибок:
res.status(400).json({
success: false,
error: {
code: "INVALID_NUMBERS", // или "DIVISION_BY_ZERO"
message: "Оба параметра должны быть числами"
}
});
Примеры кодов ошибок:
"INVALID_NUMBERS"— когда параметры не числа"DIVISION_BY_ZERO"— когда делим на ноль
