589 lines
32 KiB
Markdown
589 lines
32 KiB
Markdown
# Разрабатываем первое Web API на Node.js
|
||
|
||
Для секции "Веб-разработка: пример Fullstack"
|
||
|
||
## Введение
|
||
Урок предназачен для аудитории, имеющей базовые навыки работы с HTML/CSS, Git и SSH. Цель: освоить основы разработки Web API с использованием Node.js и фреймворка Express за ограниченное время (3 часа).
|
||
|
||
Рекомендую [очень хороший ресурс с теорией и практикой по Node.js](https://metanit.com/web/nodejs/1.1.php)
|
||
|
||
---
|
||
|
||
## 📘 **Урок 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**
|
||
- [Metanit: Файл package.json и конфигурация проекта](https://metanit.com/web/nodejs/2.7.php)
|
||
### **Цель урока**: Создать структуру папок для backend и инициализировать проект Node.js.
|
||
|
||
### **Краткая теория**:
|
||
- **Node.js** — это среда выполнения JavaScript вне браузера, которая позволяет создавать серверные приложения.
|
||
- **package.json** — это файл манифеста проекта Node.js, который содержит его описание, версию, список зависимостей и скриптов.
|
||
|
||
### **Практические шаги**:
|
||
1. **Создайте папку `backend`** внутри проекта и перейдите в неё. Можно сделать это в Git Bash:
|
||
```bash
|
||
mkdir backend
|
||
cd backend
|
||
```
|
||
2. **Инициализируйте проект Node.js**. Используйте флаг `-y`, чтобы принять значения по умолчанию.
|
||
```bash
|
||
npm init -y
|
||
|
||
# Нужно для поддержи современного синтаксиса ES Module
|
||
npm pkg set type="module";
|
||
```
|
||
|
||
### **Проверка результата**:
|
||
Убедитесь, что в папке `backend` появился файл `package.json`. В его первой строке должно быть указано `"type": "module"`.
|
||
|
||
---
|
||
|
||
## 🚀 **Урок 3: Установка фреймворка Express**
|
||
- [Metanit: Начало работы с Express](https://metanit.com/web/nodejs/4.1.php)
|
||
### **Цель урока**: Установить библиотеку Express — популярный фреймворк для создания веб-приложений и API на Node.js.
|
||
|
||
### **Краткая теория**:
|
||
- **Express** — это минималистичный и гибкий фреймворк, который значительно упрощает создание серверных приложений и маршрутов.
|
||
- **Зависимости (dependencies)** — это сторонние библиотеки (пакеты), которые использует ваш проект. Они управляются с помощью `npm` (Node Package Manager).
|
||
|
||
### **Практические шаги**:
|
||
В папке `backend` выполните команду установки:
|
||
```bash
|
||
npm install express
|
||
```
|
||
|
||
### **Что должно получиться**:
|
||
* В файле `package.json` в раздел `"dependencies"` добавится `"express"` с номером версии.
|
||
* В проекте появится папка `node_modules`, где хранятся все установленные библиотеки.
|
||
|
||
---
|
||
|
||
## 🗑️ **Урок 4: Работа с `.gitignore` и первый коммит**
|
||
[Atlassian: Файл .gitignore — игнорирование файлов в Git](https://www.atlassian.com/ru/git/tutorials/saving-changes/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 .
|
||
|
||
# Убедитесь, что папка node_modules не добавилась и зафиксируйте изменения с комментарием
|
||
git commit -m "feat: инициализирован проект Node.js с Express, добавлен .gitignore"
|
||
```
|
||
|
||
---
|
||
|
||
## 📄 **Урок 5: Создание базовой структуры сервера**
|
||
- [MDN: Введение в Express/Node](https://developer.mozilla.org/ru/docs/Learn_web_development/Extensions/Server-side/Express_Nodejs/Introduction)
|
||
- [Habr: Лучшие практики Node.js — советы по структуре проектов](https://habr.com/ru/articles/454476/)
|
||
|
||
### **Цель урока**: Создать основные файлы приложения и понять их роль.
|
||
|
||
### **Краткая теория**:
|
||
Серверное приложение на Express обычно разделяют на несколько файлов для лучшей организации:
|
||
- **`server.js`** — точка входа. Запускает сервер, подключает основные настройки.
|
||
- **`app.js`** — ядро приложения. Содержит настройки Express и все маршруты (routes).
|
||
|
||
При этом также создаются отдельные папки и файлы под разные части проекта. Например, для:
|
||
- базы данных;
|
||
- утилит;
|
||
- объектов;
|
||
- маршрутов;
|
||
и так далее. В нашем примере мы ограничимся работой в двух файлах: **`server.js`** и **`app.js`**, а более мощную файловую структуру изучим позже.
|
||
|
||
### **Практические шаги**:
|
||
1. В папке `backend` создайте папку `src`.
|
||
2. Внутри `src` создайте два файла: `app.js` и `server.js`.
|
||
3. **В файл `app.js`** пока добавьте только создание экземпляра приложения:
|
||
```javascript
|
||
// backend/src/app.js
|
||
import express from 'express';
|
||
|
||
// Создание экземпляра приложения Express
|
||
const app = express();
|
||
|
||
export default app; // Экспортируем app для использования в server.js
|
||
```
|
||
4. **В файл `server.js`** добавьте код запуска сервера:
|
||
```javascript
|
||
// backend/src/server.js
|
||
import app from './app.js';
|
||
|
||
// Выбираем порт из файла конфигурации .env, либо используем порт 3000 по умолчанию
|
||
const PORT = process.env.PORT || 3000;
|
||
|
||
app.listen(PORT, function() {
|
||
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 (конечной точке/endpoint) и HTTP-методу (GET, POST и т.д.).
|
||
- **Обработчик (handler)** — функция, которая принимает запрос (`req`) и формирует ответ (`res`).
|
||
|
||
### **Практические шаги**:
|
||
1. Откройте файл `backend/src/app.js`.
|
||
2. **Добавьте обработчик для корневого маршрута (`/`) перед строкой `export default app;`**:
|
||
```javascript
|
||
// Обработчик GET-запроса на корневой URL '/'
|
||
app.get('/', function(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)**
|
||
- [Expressjs: Маршрутизация в Express](https://www.expressjs.com.cn/ru/guide/routing.html)
|
||
- [Nodejsdev: Как построить REST API с помощью JS, Node.js и Express.js](https://nodejsdev.ru/guides/rest-api-design/)
|
||
|
||
### **Цель урока**: Научиться создавать динамические маршруты и извлекать данные из 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', function(req, res) {
|
||
const name = req.params.name; // = "Максим"
|
||
res.send(`Привет, ${name}!`);
|
||
});
|
||
```
|
||
|
||
2. **Несколько параметров**:
|
||
```javascript
|
||
// Когда заходят на /book/сказки/5
|
||
app.get('/book/:genre/:page', function(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', function(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', function(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**
|
||
- [MDN: Работа с JSON](https://developer.mozilla.org/ru/docs/Learn_web_development/Core/Scripting/JSON)
|
||
- [Microsoft Learn: Создание API, получающего JSON](https://learn.microsoft.com/ru-ru/shows/beginners-series-to-nodejs/how-to-create-an-api-that-receive-json-with-nodejs-and-express-20-of-26)
|
||
|
||
### **Цель урока**: Понять, что такое 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', function(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"` — когда делим на ноль
|
||
|
||
---
|
||
|
||
# 👷 **Дополнительные задания (повышенная сложность!)**
|
||
|
||
## 📝 Задание 1: Использование POST и DELETE методов для редактирования текста в объявлении сайта
|
||
|
||
### Цель задания
|
||
Научиться использовать методы POST и DELETE для изменения данных на сервере, понять разницу между методами, которые только читают данные (GET) и теми, которые их изменяют.
|
||
|
||
### Теория: HTTP-методы и состояние сервера
|
||
HTTP-методы определяют тип операции, которую мы хотим выполнить. GET используется для получения данных без изменений, POST — для создания или отправки новых данных, DELETE — для удаления данных.
|
||
|
||
В этом задании вы будете использовать переменную на сервере для хранения состояния приложения между запросами. Это означает, что все пользователи, которые обращаются к серверу, будут видеть одно и то же объявление.
|
||
|
||
### Практическая задача
|
||
Создайте API для управления объявлением на сайте с тремя методами:
|
||
|
||
1. **Просмотр объявления** — GET `/api/ad`
|
||
Возвращает текущее объявление или сообщение о его отсутствии.
|
||
|
||
2. **Установка объявления** — POST `/api/ad`
|
||
Устанавливает новое объявление, отправленное в теле запроса.
|
||
|
||
3. **Очистка объявления** — DELETE `/api/ad`
|
||
Полностью удаляет текущее объявление.
|
||
|
||
### Как реализовать
|
||
|
||
Начните с создания переменной для хранения объявления в начале файла `app.js`, после импортов. Например: `let currentAd = null;`
|
||
|
||
Для GET-метода проверьте, есть ли значение в переменной `currentAd`. Если объявление существует — верните его, если нет — сообщите, что объявление не установлено.
|
||
|
||
Для POST-метода потребуется middleware `express.json()` для чтения JSON из тела запроса. Добавьте строку `app.use(express.json())` в `app.js` после создания экземпляра приложения. В обработчике POST получите текст объявления из `req.body.text` и сохраните его в переменную `currentAd`.
|
||
|
||
DELETE-метод должен просто устанавливать `currentAd = null` и возвращать подтверждение удаления.
|
||
|
||
### Важные вопросы для обсуждения
|
||
- Почему для изменения данных лучше использовать POST, а не GET?
|
||
- Как данные сохраняются между запросами разных пользователей?
|
||
- Что произойдет с объявлением при перезапуске сервера?
|
||
|
||
Для тестирования этих методов вам понадобится специальный инструмент вроде cURL или Postman, так как браузер по умолчанию отправляет только GET-запросы.
|
||
|
||
---
|
||
|
||
## 📒 Задание 2: "Ящик заметок" с использованием массива
|
||
|
||
### Цель задания
|
||
Научиться работать с массивами в JavaScript и реализовать базовые CRUD-операции (Create, Read, Update, Delete).
|
||
|
||
### Теория: Массивы в JavaScript
|
||
Массив — это упорядоченный список элементов. Создать массив можно так: `let notes = []` (пустой массив) или `let notes = ["Первая заметка", "Вторая"]` (массив с данными).
|
||
|
||
Основные операции с массивами:
|
||
- Добавление элемента: `notes.push("Новая заметка")`
|
||
- Получение элемента: `notes[0]` (первый элемент, индексы начинаются с 0)
|
||
- Удаление элемента: `notes.splice(индекс, 1)`
|
||
- Длина массива: `notes.length`
|
||
|
||
### Теория: CRUD-операции
|
||
CRUD — это основа большинства веб-приложений:
|
||
- **Create** (Создать) — добавление новой заметки (POST)
|
||
- **Read** (Чтение) — получение списка или одной заметки (GET)
|
||
- **Update** (Обновление) — изменение существующей заметки (PUT/PATCH)
|
||
- **Delete** (Удаление) — удаление заметки (DELETE)
|
||
|
||
### Практическая задача
|
||
Создайте полноценное API для управления заметками с четырьмя операциями:
|
||
|
||
1. **Получить все заметки** — GET `/api/notes`
|
||
2. **Добавить заметку** — POST `/api/notes`
|
||
3. **Получить одну заметку** — GET `/api/notes/:id`
|
||
4. **Удалить заметку** — DELETE `/api/notes/:id`
|
||
|
||
### Как реализовать
|
||
|
||
Создайте массив для хранения заметок и счетчик для ID:
|
||
```javascript
|
||
let notes = [];
|
||
let nextId = 1;
|
||
```
|
||
|
||
Для GET `/api/notes` просто верните весь массив `notes` в формате JSON.
|
||
|
||
Для POST `/api/notes` получите текст заметки из `req.body.text`, создайте объект заметки с уникальным ID и текущей датой, добавьте его в массив с помощью `push()`, увеличьте `nextId` и верните созданную заметку.
|
||
|
||
Для GET `/api/notes/:id` найдите заметку в массиве по ID. Используйте метод `find()`: `const note = notes.find(function(n) { return n.id === id; });`. Если заметка найдена — верните её, если нет — верните ошибку 404.
|
||
|
||
Для DELETE `/api/notes/:id` найдите индекс заметки по ID: `const index = notes.findIndex(function(n) { return n.id === id; });`, затем удалите её с помощью `splice(index, 1)` и верните подтверждение удаления.
|
||
|
||
### Важные моменты
|
||
Заметки будут храниться только в памяти сервера и исчезнут при его перезапуске. Для постоянного хранения данных потребуется база данных или файловая система, но это тема для следующих занятий.
|
||
|
||
### Вопросы для самопроверки
|
||
1. Чем отличается `notes[0]` от `notes.find(function(n) { return n.id === 1; })`?
|
||
2. Почему лучше использовать отдельный счетчик `nextId`, а не просто длину массива?
|
||
3. Какие HTTP-методы соответствуют операциям CRUD?
|
||
|
||
---
|
||
|
||

|