initial commit
This commit is contained in:
463
README.md
Normal file
463
README.md
Normal file
@@ -0,0 +1,463 @@
|
||||
# Методические указания по разработке 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](https://github.com).
|
||||
* Нажмите `+` в правом верхнем углу и выберите `New repository`.
|
||||
* В поле `Repository name` укажите название, отражающее тему вашего API (например, `my-first-api`).
|
||||
* Оставьте репозиторий публичным (`Public`).
|
||||
* **Поставьте галочку** `Add a README.md`. Это создаст начальный файл описания проекта.
|
||||
* Нажмите `Create repository`.
|
||||
|
||||
2. **Клонируйте репозиторий и создайте учебную ветку**:
|
||||
```bash
|
||||
# Склонируйте репозиторий на компьютер
|
||||
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`** и перейдите в неё:
|
||||
```bash
|
||||
mkdir backend
|
||||
cd backend
|
||||
```
|
||||
2. **Инициализируйте проект Node.js**. Используйте флаг `-y`, чтобы принять значения по умолчанию, и `--type=module` для поддержки современного синтаксиса ES-модулей:
|
||||
```bash
|
||||
npm init -y --type=module
|
||||
```
|
||||
|
||||
### **Проверка результата**:
|
||||
Убедитесь, что в папке `backend` появился файл `package.json`. В его первой строке должно быть указано `"type": "module"`.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 **Урок 3: Установка фреймворка Express**
|
||||
|
||||
### **Цель урока**: Установить библиотеку Express — популярный фреймворк для создания веб-приложений и API на Node.js.
|
||||
|
||||
### **Краткая теория**:
|
||||
- **Express** — это минималистичный и гибкий фреймворк, который значительно упрощает создание серверных приложений и маршрутов.
|
||||
- **Зависимости (dependencies)** — это сторонние библиотеки (пакеты), которые использует ваш проект. Они управляются с помощью `npm` (Node Package Manager).
|
||||
|
||||
### **Практические шаги**:
|
||||
В папке `backend` выполните команду установки:
|
||||
```bash
|
||||
npm install express
|
||||
```
|
||||
|
||||
### **Что должно получиться**:
|
||||
* В файле `package.json` в раздел `"dependencies"` добавится `"express"` с номером версии.
|
||||
* В проекте появится папка `node_modules`, где хранятся все установленные библиотеки.
|
||||
|
||||
---
|
||||
|
||||
## 🗑️ **Урок 4: Работа с `.gitignore` и первый коммит**
|
||||
|
||||
### **Цель урока**: Научиться игнорировать ненужные для репозитория файлы и зафиксировать изменения.
|
||||
|
||||
### **Краткая теория**:
|
||||
- **`node_modules`** — это папка со всеми зависимостями проекта. Её **нельзя** добавлять в Git, так как она очень большая и её можно восстановить командой `npm install`.
|
||||
- **`.gitignore`** — специальный файл, в котором перечисляются шаблоны файлов и папок, которые Git должен игнорировать.
|
||||
|
||||
### **Практические шаги**:
|
||||
1. **Создайте файл `.gitignore`** в корне вашего проекта (на одном уровне с папкой `backend`).
|
||||
2. **Добавьте в него шаблоны**. Вы можете создать базовое содержимое на сайте [gitignore.io](https://www.toptal.com/developers/gitignore). Введите `Node, Windows, VisualStudioCode` и скопируйте сгенерированный текст в ваш файл.
|
||||
3. **Убедитесь, что в `.gitignore` есть строки**:
|
||||
```
|
||||
node_modules/
|
||||
.env
|
||||
```
|
||||
4. **Выполните коммит**:
|
||||
```bash
|
||||
# Вернитесь в корень проекта (если вы в папке 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`** пока добавьте только создание экземпляра приложения:
|
||||
```javascript
|
||||
// backend/src/app.js
|
||||
import express from 'express';
|
||||
|
||||
const app = express();
|
||||
|
||||
export default app; // Экспортируем app для использования в server.js
|
||||
```
|
||||
4. **В файл `server.js`** добавьте код запуска сервера:
|
||||
```javascript
|
||||
// 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` выполните команду:
|
||||
```bash
|
||||
node src/server.js
|
||||
```
|
||||
2. В консоли должно появиться сообщение: `Сервер запущен и слушает порт 3000`.
|
||||
3. Откройте браузер и перейдите по адресу `http://localhost:3000`.
|
||||
4. **Вы должны увидеть стандартную страницу ошибки `Cannot GET /`**. Это ожидаемо, так как мы не создали обработчик для корневого маршрута (`/`).
|
||||
5. Остановите сервер, нажав `Ctrl + C` в терминале.
|
||||
6. **Выполните коммит**:
|
||||
```bash
|
||||
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;`**:
|
||||
```javascript
|
||||
// Обработчик 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. **Один параметр**:
|
||||
```javascript
|
||||
// Когда заходят на /hello/Максим
|
||||
app.get('/hello/:name', (req, res) => {
|
||||
const name = req.params.name; // = "Максим"
|
||||
res.send(`Привет, ${name}!`);
|
||||
});
|
||||
```
|
||||
|
||||
2. **Несколько параметров**:
|
||||
```javascript
|
||||
// Когда заходят на /book/сказки/5
|
||||
app.get('/book/:genre/:page', (req, res) => {
|
||||
const genre = req.params.genre; // = "сказки"
|
||||
const page = req.params.page; // = "5"
|
||||
res.send(`Жанр: ${genre}, Страница: ${page}`);
|
||||
});
|
||||
```
|
||||
|
||||
3. **Параметр в середине пути**:
|
||||
```javascript
|
||||
// Когда заходят на /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` добавьте маршрут:
|
||||
```javascript
|
||||
// Пример запроса: 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');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
2. Протестируйте:
|
||||
- `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: Проверка на число**
|
||||
В начале каждого обработчика добавьте:
|
||||
```javascript
|
||||
const a = parseFloat(req.params.a);
|
||||
const b = parseFloat(req.params.b);
|
||||
|
||||
// Проверяем, являются ли оба параметра числами
|
||||
if (isNaN(a) || isNaN(b)) {
|
||||
return res.status(400).send('Ошибка: оба параметра должны быть числами');
|
||||
}
|
||||
```
|
||||
|
||||
**Шаг 2: Проверка деления на ноль**
|
||||
Только в обработчике деления добавьте после проверки на числа:
|
||||
```javascript
|
||||
// Проверка деления на ноль
|
||||
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**:
|
||||
```json
|
||||
{
|
||||
"имя": "Иван",
|
||||
"возраст": 16,
|
||||
"хобби": ["программирование", "шахматы"],
|
||||
"студент": true
|
||||
}
|
||||
```
|
||||
|
||||
### **Практическое задание**:
|
||||
1. Создайте маршрут `GET /api/user/:id`
|
||||
2. Если `:id` — число, верните JSON с информацией о пользователе:
|
||||
```javascript
|
||||
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"
|
||||
});
|
||||
}
|
||||
});
|
||||
```
|
||||
3. Протестируйте в браузере:
|
||||
- `http://localhost:3000/api/user/123` → увидите красиво оформленный JSON
|
||||
- `http://localhost:3000/api/user/abc` → JSON с ошибкой
|
||||
|
||||
### Обратите внимание
|
||||
В примере мы возвращаем фальшивые данные. С настоящими динамическими данными (списки/объекты БД) мы поработаем позже.
|
||||
|
||||
---
|
||||
|
||||
## 🔄 **Урок 12: Калькулятор с JSON-ответами**
|
||||
|
||||
### **Цель урока**: Переделать текстовый калькулятор для возврата JSON.
|
||||
|
||||
### **Задание**:
|
||||
Измените все 4 операции калькулятора так, чтобы они возвращали данные в JSON-формате.
|
||||
|
||||
### **Формат успешного ответа**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"operation": "sum",
|
||||
"arguments": {
|
||||
"a": 5,
|
||||
"b": 3
|
||||
},
|
||||
"result": 8
|
||||
}
|
||||
```
|
||||
|
||||
### **Формат ответа с ошибкой**:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "DIVISION_BY_ZERO",
|
||||
"message": "Делитель не может быть равен нулю"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Как изменить код**:
|
||||
|
||||
1. **Заменяем `res.send()` на `res.json()`**
|
||||
2. **Для успешного ответа** формируем объект:
|
||||
```javascript
|
||||
const response = {
|
||||
success: true,
|
||||
operation: "sum", // или "subtract", "multiply", "divide"
|
||||
arguments: {
|
||||
a: a,
|
||||
b: b
|
||||
},
|
||||
result: a + b // здесь ваша операция
|
||||
};
|
||||
res.json(response);
|
||||
```
|
||||
|
||||
3. **Для ошибок**:
|
||||
```javascript
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: {
|
||||
code: "INVALID_NUMBERS", // или "DIVISION_BY_ZERO"
|
||||
message: "Оба параметра должны быть числами"
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### **Примеры кодов ошибок**:
|
||||
- `"INVALID_NUMBERS"` — когда параметры не числа
|
||||
- `"DIVISION_BY_ZERO"` — когда делим на ноль
|
||||
Reference in New Issue
Block a user