Files
lesson_2/README.md
2025-12-12 17:41:54 +03:00

23 KiB
Raw Blame History

Методические указания по разработке Web API на Node.js для школьников

Введение

Данные методические указания предназначены для школьников, имеющих базовые навыки работы с HTML/CSS, Git и SSH. Цель курса — освоить основы разработки Web API с использованием Node.js и фреймворка Express за ограниченное время (3 часа на занятие и несколько занятий в семестр). Упор сделан на практические задания с минимально необходимой теорией.


📘 Урок 1: Создание репозитория и организации структуры проекта

Цель урока: Создать GitHub-репозиторий, организовать структуру проекта и научиться работать с ветками в Git.

Краткая теория:

  • GitHub — платформа для хостинга и совместной разработки IT-проектов с использованием системы контроля версий Git.
  • Репозиторий — хранилище кода и истории его изменений.
  • Ветка (branch) — изолированная копия проекта для разработки новой функциональности без влияния на основной код (часто называется main или master).

Практические шаги:

  1. Создайте репозиторий на GitHub:

    • Авторизуйтесь на GitHub.
    • Нажмите + в правом верхнем углу и выберите New repository.
    • В поле Repository name укажите название, отражающее тему вашего API (например, my-first-api).
    • Оставьте репозиторий публичным (Public).
    • Поставьте галочку Add a README.md. Это создаст начальный файл описания проекта.
    • Нажмите Create repository.
  2. Клонируйте репозиторий и создайте учебную ветку:

    # Склонируйте репозиторий на компьютер
    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, который содержит его описание, версию, список зависимостей и скриптов.

Практические шаги:

  1. Создайте папку backend и перейдите в неё:
    mkdir backend
    cd backend
    
  2. Инициализируйте проект 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 и первый коммит

Цель урока: Научиться игнорировать ненужные для репозитория файлы и зафиксировать изменения.

Краткая теория:

  • node_modules — это папка со всеми зависимостями проекта. Её нельзя добавлять в Git, так как она очень большая и её можно восстановить командой npm install.
  • .gitignore — специальный файл, в котором перечисляются шаблоны файлов и папок, которые Git должен игнорировать.

Практические шаги:

  1. Создайте файл .gitignore в корне вашего проекта (на одном уровне с папкой backend).
  2. Добавьте в него шаблоны. Вы можете создать базовое содержимое на сайте gitignore.io. Введите Node, Windows, VisualStudioCode и скопируйте сгенерированный текст в ваш файл.
  3. Убедитесь, что в .gitignore есть строки:
    node_modules/
    .env
    
  4. Выполните коммит:
    # Вернитесь в корень проекта (если вы в папке backend)
    cd ..
    
    # Добавьте все новые файлы в staging area
    git add .
    
    # Зафиксируйте изменения с комментарием
    git commit -m "feat: инициализирован проект Node.js с Express, добавлен .gitignore"
    

📄 Урок 5: Создание базовой структуры сервера

Цель урока: Создать основные файлы приложения и понять их роль.

Краткая теория:

Серверное приложение на Express обычно разделяют на несколько файлов для лучшей организации:

  • server.js — точка входа. Запускает сервер, подключает основные настройки.
  • app.js — ядро приложения. Содержит настройки Express и все маршруты (routes).

Практические шаги:

  1. В папке backend создайте папку src.
  2. Внутри src создайте два файла: app.js и server.js.
  3. В файл app.js пока добавьте только создание экземпляра приложения:
    // backend/src/app.js
    import express from 'express';
    
    const app = express();
    
    export default app; // Экспортируем app для использования в server.js
    
  4. В файл 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: Первый запуск сервера

Цель урока: Запустить сервер и убедиться, что он работает, возвращая ожидаемую ошибку.

Практические шаги:

  1. Из папки backend выполните команду:
    node src/server.js
    
  2. В консоли должно появиться сообщение: Сервер запущен и слушает порт 3000.
  3. Откройте браузер и перейдите по адресу http://localhost:3000.
  4. Вы должны увидеть стандартную страницу ошибки Cannot GET /. Это ожидаемо, так как мы не создали обработчик для корневого маршрута (/).
  5. Остановите сервер, нажав Ctrl + C в терминале.
  6. Выполните коммит:
    git add .
    git commit -m "feat: создана базовая структура сервера, успешный запуск"
    git push origin study # Или study-фамилия
    

🖐️ Урок 7: Создание первого маршрута (Hello World)

Цель урока: Создать простейший обработчик GET-запроса и получить ответ от сервера.

Краткая теория:

  • Маршрут (route) — это правило, которое определяет, как сервер будет реагировать на клиентский запрос к определенному URL (конечной точке) и HTTP-методу (GET, POST и т.д.).
  • Обработчик (handler) — функция, которая принимает запрос (req) и формирует ответ (res).

Практические шаги:

  1. Откройте файл backend/src/app.js.
  2. Добавьте обработчик для корневого маршрута (/) перед строкой export default app;:
    // Обработчик GET-запроса на корневой URL '/'
    app.get('/', (req, res) => {
        // Устанавливаем заголовок ответа
        res.setHeader('Content-Type', 'text/plain');
        // Отправляем текстовый ответ
        res.send('Hello World from my API!');
    });
    
  3. Запустите сервер снова (node src/server.js) и обновите страницу http://localhost:3000 в браузере.
  4. Вы должны увидеть надпись Hello World from my API!.
  5. Выполните коммит.

🔢 Урок 8: Работа с параметрами пути (Path Parameters)

Цель урока: Научиться создавать динамические маршруты и извлекать данные из URL.

Краткая теория:

  • Статические маршруты — это фиксированные адреса, например, /about или /contacts. Они всегда одинаковы.
  • Динамические маршруты — это адреса, которые могут меняться. Например, страница профиля с разными именами пользователей: /user/anna, /user/max.
  • Параметры пути (Path Parameters) — специальные части URL, которые меняются. В Express они обозначаются двоеточием (:), например: /user/:username.
  • Когда кто-то заходит на /user/anna, Express видит :username в маршруте и понимает: "вместо :username подставлено anna". Это значение сохраняется в req.params.

Примеры разных параметров:

  1. Один параметр:
// Когда заходят на /hello/Максим
app.get('/hello/:name', (req, res) => {
    const name = req.params.name; // = "Максим"
    res.send(`Привет, ${name}!`);
});
  1. Несколько параметров:
// Когда заходят на /book/сказки/5
app.get('/book/:genre/:page', (req, res) => {
    const genre = req.params.genre; // = "сказки"
    const page = req.params.page;   // = "5"
    res.send(`Жанр: ${genre}, Страница: ${page}`);
});
  1. Параметр в середине пути:
// Когда заходят на /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}`);
});

Практические шаги:

  1. В файле 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');
    }
});
  1. Протестируйте:
    • http://localhost:3000/double/7 → работает
    • http://localhost:3000/double/abc → ошибка

✖️ Урок 9: Практическое задание — Текстовый API-калькулятор

Цель задания: Создать простой калькулятор, который принимает числа в URL и возвращает текстовый результат.

Задание:

Создайте 4 маршрута для основных математических операций. Формат ответа — обычный текст.

Маршруты и примеры:

  1. Сложение: GET /api/calc/sum/:a/:b

    • Пример: GET /api/calc/sum/5/3
    • Ответ: 5 + 3 = 8
  2. Вычитание: GET /api/calc/subtract/:a/:b

    • Пример: GET /api/calc/subtract/10/4
    • Ответ: 10 - 4 = 6
  3. Умножение: GET /api/calc/multiply/:a/:b

    • Пример: GET /api/calc/multiply/7/2
    • Ответ: 7 * 2 = 14
  4. Деление: GET /api/calc/divide/:a/:b

    • Пример: GET /api/calc/divide/15/3
    • Ответ: 15 / 3 = 5

Как это сделать:

  1. Для каждого маршрута получите параметры из req.params.a и req.params.b
  2. Преобразуйте их в числа: const num1 = parseFloat(req.params.a)
  3. Выполните операцию
  4. Верните ответ в формате: res.send(`${num1} + ${num2} = ${result}`)

Важно:

  • Пока не нужно проверять, корректные ли данные прислал пользователь
  • Используйте шаблонные строки (обратные кавычки) для формирования ответа

⚠️ Урок 10: Базовые проверки в калькуляторе

Цель урока: Добавить минимальную проверку входных данных.

Задание:

Доработайте калькулятор из урока 9, добавив две простые проверки:

  1. Проверка, что оба параметра — числа
  2. Для деления — проверка, что второй параметр не ноль

Как это сделать:

Шаг 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/35 + 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
}

Практическое задание:

  1. Создайте маршрут GET /api/user/:id
  2. Если :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"
        });
    }
});
  1. Протестируйте в браузере:
    • http://localhost:3000/api/user/123 → увидите красиво оформленный JSON
    • http://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": "Делитель не может быть равен нулю"
  }
}

Как изменить код:

  1. Заменяем res.send() на res.json()
  2. Для успешного ответа формируем объект:
const response = {
    success: true,
    operation: "sum", // или "subtract", "multiply", "divide"
    arguments: {
        a: a,
        b: b
    },
    result: a + b // здесь ваша операция
};
res.json(response);
  1. Для ошибок:
res.status(400).json({
    success: false,
    error: {
        code: "INVALID_NUMBERS", // или "DIVISION_BY_ZERO"
        message: "Оба параметра должны быть числами"
    }
});

Примеры кодов ошибок:

  • "INVALID_NUMBERS" — когда параметры не числа
  • "DIVISION_BY_ZERO" — когда делим на ноль