feat-theory #1
98
README.md
98
README.md
@@ -5,7 +5,7 @@
|
|||||||
Для секции "Веб-разработка: пример Fullstack"
|
Для секции "Веб-разработка: пример Fullstack"
|
||||||
|
|
||||||
## Введение
|
## Введение
|
||||||
Урок предназачен для аудитории, имеющей базовые навыки работы с HTML/CSS, Git и SSH. Цель: освоить основы разработки Web API с использованием Node.js и фреймворка Express за ограниченное время (3 часа).
|
Урок предназначен для аудитории, имеющей базовые навыки работы с HTML/CSS, Git и SSH. Цель: освоить основы разработки Web API с использованием Node.js и фреймворка Express за ограниченное время (3 часа).
|
||||||
|
|
||||||
Рекомендую [очень хороший ресурс с теорией и практикой по Node.js](https://metanit.com/web/nodejs/1.1.php)
|
Рекомендую [очень хороший ресурс с теорией и практикой по Node.js](https://metanit.com/web/nodejs/1.1.php)
|
||||||
|
|
||||||
@@ -20,6 +20,9 @@
|
|||||||
- **Репозиторий** — хранилище кода и истории его изменений.
|
- **Репозиторий** — хранилище кода и истории его изменений.
|
||||||
- **Ветка (branch)** — изолированная копия проекта для разработки новой функциональности без влияния на основной код (часто называется `main` или `master`).
|
- **Ветка (branch)** — изолированная копия проекта для разработки новой функциональности без влияния на основной код (часто называется `main` или `master`).
|
||||||
|
|
||||||
|
### **Теория: Для чего создавать репозиторий и ветки**
|
||||||
|
Создание репозитория — это первый шаг к организации вашего кода в профессиональной среде. Репозиторий хранит не только текущую версию проекта, но и всю историю изменений, что позволяет отслеживать, кто, когда и какие правки вносил. Это критически важно для командной работы, так как позволяет нескольким разработчикам работать над одним проектом одновременно, не мешая друг другу. Ветки в Git создаются для изоляции новой функциональности или экспериментов от основного кода. Вы работаете в своей ветке, и пока вы не объедините её с основной, ваши изменения не повлияют на стабильную версию проекта. Это позволяет безопасно тестировать новые идеи и реализовывать фичи без риска сломать уже работающую систему.
|
||||||
|
|
||||||
### **Практические шаги**:
|
### **Практические шаги**:
|
||||||
1. **Создайте репозиторий на GitHub**:
|
1. **Создайте репозиторий на GitHub**:
|
||||||
* Авторизуйтесь на [GitHub](https://github.com).
|
* Авторизуйтесь на [GitHub](https://github.com).
|
||||||
@@ -56,6 +59,9 @@
|
|||||||
- **Node.js** — это среда выполнения JavaScript вне браузера, которая позволяет создавать серверные приложения.
|
- **Node.js** — это среда выполнения JavaScript вне браузера, которая позволяет создавать серверные приложения.
|
||||||
- **package.json** — это файл манифеста проекта Node.js, который содержит его описание, версию, список зависимостей и скриптов.
|
- **package.json** — это файл манифеста проекта Node.js, который содержит его описание, версию, список зависимостей и скриптов.
|
||||||
|
|
||||||
|
### **Теория: Почему нужны Node.js и package.json**
|
||||||
|
Node.js преобразует JavaScript из языка, работающего только в браузере, в полноценный инструмент для создания серверной логики. Это означает, что вы можете писать код, который будет выполняться на сервере, обрабатывать запросы от клиентов (например, браузеров или мобильных приложений), работать с базами данных и возвращать результаты. Файл `package.json` является сердцем любого проекта на Node.js. В нём описывается проект: его название, версия, автор. Но главное — он хранит список всех внешних библиотек (зависимостей), которые использует ваш проект. Это позволяет любому другому разработчику склонировать ваш проект и одной командой установить всё необходимое для его работы. Установка `"type": "module"` говорит Node.js использовать современный синтаксис модулей (import/export) вместо устаревшего CommonJS, что делает код более стандартизированным и удобным для чтения.
|
||||||
|
|
||||||
### **Практические шаги**:
|
### **Практические шаги**:
|
||||||
1. **Создайте папку `backend`** внутри проекта и перейдите в неё. Можно сделать это в Git Bash:
|
1. **Создайте папку `backend`** внутри проекта и перейдите в неё. Можно сделать это в Git Bash:
|
||||||
```bash
|
```bash
|
||||||
@@ -83,6 +89,9 @@
|
|||||||
- **Express** — это минималистичный и гибкий фреймворк, который значительно упрощает создание серверных приложений и маршрутов.
|
- **Express** — это минималистичный и гибкий фреймворк, который значительно упрощает создание серверных приложений и маршрутов.
|
||||||
- **Зависимости (dependencies)** — это сторонние библиотеки (пакеты), которые использует ваш проект. Они управляются с помощью `npm` (Node Package Manager).
|
- **Зависимости (dependencies)** — это сторонние библиотеки (пакеты), которые использует ваш проект. Они управляются с помощью `npm` (Node Package Manager).
|
||||||
|
|
||||||
|
### **Теория: Роль Express и менеджера пакетов npm**
|
||||||
|
Node.js сам по себе предоставляет базовые инструменты для работы с сетью, но писать на чистом Node.js сложно и долго. Express — это фреймворк, который добавляет над Node.js слой абстракции. Он предоставляет простые и понятные методы для описания маршрутов (URL-адресов, на которые реагирует сервер), обработки HTTP-запросов (GET, POST и других) и формирования ответов. Без Express пришлось бы вручную разбирать заголовки запросов и собирать ответы, что является рутинной и ошибкоопасной работой. npm (Node Package Manager) — это инструмент для управления зависимостями. Когда вы устанавливаете Express командой `npm install express`, npm скачивает библиотеку и все её зависимости из центрального репозитория в папку `node_modules` и фиксирует точную версию в `package.json`. Это гарантирует, что у всех разработчиков проекта будут одинаковые версии библиотек, что предотвращает проблемы с совместимостью.
|
||||||
|
|
||||||
### **Практические шаги**:
|
### **Практические шаги**:
|
||||||
В папке `backend` выполните команду установки:
|
В папке `backend` выполните команду установки:
|
||||||
```bash
|
```bash
|
||||||
@@ -104,6 +113,9 @@ npm install express
|
|||||||
- **`node_modules`** — это папка со всеми зависимостями проекта. Её **нельзя** добавлять в Git, так как она очень большая и её можно восстановить командой `npm install`.
|
- **`node_modules`** — это папка со всеми зависимостями проекта. Её **нельзя** добавлять в Git, так как она очень большая и её можно восстановить командой `npm install`.
|
||||||
- **`.gitignore`** — специальный файл, в котором перечисляются шаблоны файлов и папок, которые Git должен игнорировать.
|
- **`.gitignore`** — специальный файл, в котором перечисляются шаблоны файлов и папок, которые Git должен игнорировать.
|
||||||
|
|
||||||
|
### **Теория: Контроль версий и игнорирование файлов**
|
||||||
|
Система контроля версий Git предназначена для отслеживания изменений в исходном коде, а не в сгенерированных файлах или конфиденциальных данных. Папка `node_modules` содержит тысячи файлов установленных библиотек. Её размер может составлять сотни мегабайт. Хранить её в Git неэффективно, потому что её всегда можно восстановить по информации из `package.json` командой `npm install`. Файл `.gitignore` — это набор правил для Git. Каждая строка в этом файле — это паттерн (например, `node_modules/` или `*.log`), который указывает Git, какие файлы или папки следует полностью игнорировать и не включать в репозиторий. Это помогает сохранять репозиторий чистым, небольшим и безопасным (например, игнорируя файлы с паролями `.env`). Создание коммита — это операция фиксации текущего состояния вашего кода в истории Git. Каждый коммит имеет уникальный идентификатор и сообщение, описывающее изменения. Это позволяет в любой момент вернуться к любой ранее сохранённой версии проекта.
|
||||||
|
|
||||||
### **Практические шаги**:
|
### **Практические шаги**:
|
||||||
1. **Создайте файл `.gitignore`** в основной папке вашего проекта (не внутри `backend`).
|
1. **Создайте файл `.gitignore`** в основной папке вашего проекта (не внутри `backend`).
|
||||||
2. **Добавьте в него шаблоны**. Вы можете создать базовое содержимое на сайте [gitignore.io](https://www.toptal.com/developers/gitignore). Введите `Node, Windows, VisualStudioCode` и скопируйте сгенерированный текст в ваш файл.
|
2. **Добавьте в него шаблоны**. Вы можете создать базовое содержимое на сайте [gitignore.io](https://www.toptal.com/developers/gitignore). Введите `Node, Windows, VisualStudioCode` и скопируйте сгенерированный текст в ваш файл.
|
||||||
@@ -137,12 +149,63 @@ npm install express
|
|||||||
- **`server.js`** — точка входа. Запускает сервер, подключает основные настройки.
|
- **`server.js`** — точка входа. Запускает сервер, подключает основные настройки.
|
||||||
- **`app.js`** — ядро приложения. Содержит настройки Express и все маршруты (routes).
|
- **`app.js`** — ядро приложения. Содержит настройки Express и все маршруты (routes).
|
||||||
|
|
||||||
При этом также создаются отдельные папки и файлы под разные части проекта. Например, для:
|
### **Теория: Архитектура серверного приложения**
|
||||||
- базы данных;
|
Разделение кода на разные файлы (`app.js` и `server.js`) следует принципу разделения ответственности. `app.js` отвечает за логику приложения: настройку middleware (промежуточного ПО), определение всех маршрутов и обработчиков. `server.js` отвечает за инфраструктуру: запуск HTTP-сервера на определённом порту и обработку сетевых соединений. Такое разделение делает код модульным и тестируемым. Вы можете импортировать объект `app` из `app.js` в тесты, не запуская реальный сервер. Переменная окружения `process.env.PORT` используется для настройки порта. На локальной машине вы используете порт 3000, но когда приложение размещается на хостинге (например, Heroku или Render), платформа сама назначает порт через эту переменную. Это стандартный подход для облачных сервисов.
|
||||||
- утилит;
|
|
||||||
- объектов;
|
В нашем примере мы используем максимально базовую файловую структуру. Настоящие приложения, как правило, очень сложные. Для того, чтобы их было удобно поддерживать, используют более сложную, но при этом изящную и удобную файлову структуру. Пример того, как могло бы выглядеть приложение в продакшене:
|
||||||
- маршрутов;
|
```
|
||||||
и так далее. В нашем примере мы ограничимся работой в двух файлах: **`server.js`** и **`app.js`**, а более мощную файловую структуру изучим позже.
|
my-first-api/
|
||||||
|
├── backend/
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── app.js # Ядро приложения: настройки Express, middleware
|
||||||
|
│ │ ├── server.js # Точка входа: запуск сервера
|
||||||
|
│ │ ├── config/ # Конфигурационные файлы
|
||||||
|
│ │ │ ├── database.js # Настройки подключения к БД
|
||||||
|
│ │ │ └── constants.js # Константы приложения
|
||||||
|
│ │ ├── routes/ # Папка для всех маршрутов
|
||||||
|
│ │ │ ├── api/ # API маршруты
|
||||||
|
│ │ │ │ ├── index.js # Объединяет все API-маршруты
|
||||||
|
│ │ │ │ ├── users.js # Маршруты для работы с пользователями
|
||||||
|
│ │ │ │ ├── posts.js # Маршруты для работы с постами
|
||||||
|
│ │ │ │ └── auth.js # Маршруты для аутентификации
|
||||||
|
│ │ │ └── web.js # Веб-маршруты (если есть HTML-страницы)
|
||||||
|
│ │ ├── controllers/ # Контроллеры (обработчики маршрутов)
|
||||||
|
│ │ │ ├── userController.js
|
||||||
|
│ │ │ ├── postController.js
|
||||||
|
│ │ │ └── authController.js
|
||||||
|
│ │ ├── models/ # Модели данных (структура БД)
|
||||||
|
│ │ │ ├── User.js
|
||||||
|
│ │ │ ├── Post.js
|
||||||
|
│ │ │ └── index.js # Инициализация всех моделей
|
||||||
|
│ │ ├── middleware/ # Промежуточное ПО (middleware)
|
||||||
|
│ │ │ ├── auth.js # Проверка авторизации
|
||||||
|
│ │ │ ├── validation.js # Валидация данных
|
||||||
|
│ │ │ └── errorHandler.js # Обработка ошибок
|
||||||
|
│ │ ├── services/ # Бизнес-логика (сервисный слой)
|
||||||
|
│ │ │ ├── userService.js
|
||||||
|
│ │ │ └── postService.js
|
||||||
|
│ │ ├── utils/ # Вспомогательные функции
|
||||||
|
│ │ │ ├── helpers.js
|
||||||
|
│ │ │ ├── validators.js
|
||||||
|
│ │ │ └── logger.js # Логирование
|
||||||
|
│ │ └── public/ # Статические файлы (CSS, JS, изображения)
|
||||||
|
│ │ ├── css/
|
||||||
|
│ │ ├── js/
|
||||||
|
│ │ └── images/
|
||||||
|
│ ├── tests/ # Тесты
|
||||||
|
│ │ ├── unit/ # Модульные тесты
|
||||||
|
│ │ └── integration/ # Интеграционные тесты
|
||||||
|
│ ├── .env # Переменные окружения (НЕ коммитить в Git!)
|
||||||
|
│ ├── .env.example # Пример .env файла (без реальных значений)
|
||||||
|
│ ├── package.json
|
||||||
|
│ └── package-lock.json
|
||||||
|
├── frontend/ # Если это fullstack-проект
|
||||||
|
│ ├── src/
|
||||||
|
│ └── public/
|
||||||
|
├── .gitignore
|
||||||
|
├── README.md
|
||||||
|
└── docker-compose.yml # Если используется Docker
|
||||||
|
```
|
||||||
|
|
||||||
### **Практические шаги**:
|
### **Практические шаги**:
|
||||||
1. В папке `backend` создайте папку `src`.
|
1. В папке `backend` создайте папку `src`.
|
||||||
@@ -179,6 +242,9 @@ npm install express
|
|||||||
|
|
||||||
### **Цель урока**: Запустить сервер и убедиться, что он работает, возвращая ожидаемую ошибку.
|
### **Цель урока**: Запустить сервер и убедиться, что он работает, возвращая ожидаемую ошибку.
|
||||||
|
|
||||||
|
### **Теория: Жизненный цикл HTTP-запроса и обработка ошибок**
|
||||||
|
Когда вы вводите адрес в браузере, браузер отправляет HTTP-запрос на указанный сервер и порт. Запущенное приложение Node.js с Express прослушивает этот порт и получает запрос. Express проверяет, есть ли зарегистрированный маршрут (обработчик), который соответствует URL и методу запроса. Если маршрут не найден, Express автоматически генерирует и отправляет обратно ответ с HTTP-статусом `404 (Not Found)` и стандартной HTML-страницей ошибки. Сообщение "Cannot GET /" прямо указывает, что для метода `GET` по пути `/` обработчик не найден. Успешный запуск сервера и получение этой ошибки — важный этап. Он подтверждает, что серверная часть работает, сетевые подключения устанавливаются, и фреймворк Express корректно обрабатывает входящие запросы. Теперь ваша задача — научить сервер правильно на них отвечать.
|
||||||
|
|
||||||
### **Практические шаги**:
|
### **Практические шаги**:
|
||||||
1. Из папки `backend` выполните команду:
|
1. Из папки `backend` выполните команду:
|
||||||
```bash
|
```bash
|
||||||
@@ -205,6 +271,9 @@ npm install express
|
|||||||
- **Маршрут (route)** — это правило, которое определяет, как сервер будет реагировать на клиентский запрос к определенному URL (конечной точке/endpoint) и HTTP-методу (GET, POST и т.д.).
|
- **Маршрут (route)** — это правило, которое определяет, как сервер будет реагировать на клиентский запрос к определенному URL (конечной точке/endpoint) и HTTP-методу (GET, POST и т.д.).
|
||||||
- **Обработчик (handler)** — функция, которая принимает запрос (`req`) и формирует ответ (`res`).
|
- **Обработчик (handler)** — функция, которая принимает запрос (`req`) и формирует ответ (`res`).
|
||||||
|
|
||||||
|
### **Теория: Механизм маршрутизации в Express**
|
||||||
|
Метод `app.get()` регистрирует обработчик для GET-запросов по указанному пути. Первый аргумент — это путь (`'/'`), второй — функция-обработчик. Когда приходит запрос, Express сравнивает его метод и URL с зарегистрированными маршрутами и выполняет функцию первого подходящего. Функция-обработчик получает два объекта: `req` (запрос) и `res` (ответ). `req` содержит информацию о входящем запросе: заголовки, параметры, тело. `res` используется для формирования и отправки ответа клиенту. `res.setHeader()` устанавливает HTTP-заголовки ответа. Заголовок `Content-Type: text/plain` сообщает клиенту, что тело ответа — простой текст, а не HTML или JSON. `res.send()` завершает запрос, отправляет указанные данные и закрывает соединение. Это базовый строительный блок любого Web API — связь URL с конкретной функцией, выполняющей полезную работу.
|
||||||
|
|
||||||
### **Практические шаги**:
|
### **Практические шаги**:
|
||||||
1. Откройте файл `backend/src/app.js`.
|
1. Откройте файл `backend/src/app.js`.
|
||||||
2. **Добавьте обработчик для корневого маршрута (`/`) перед строкой `export default app;`**:
|
2. **Добавьте обработчик для корневого маршрута (`/`) перед строкой `export default app;`**:
|
||||||
@@ -235,6 +304,9 @@ npm install express
|
|||||||
- **Параметры пути (Path Parameters)** — специальные части URL, которые меняются. В Express они обозначаются двоеточием (`:`), например: `/user/:username`.
|
- **Параметры пути (Path Parameters)** — специальные части URL, которые меняются. В Express они обозначаются двоеточием (`:`), например: `/user/:username`.
|
||||||
- Когда кто-то заходит на `/user/anna`, Express видит `:username` в маршруте и понимает: "вместо `:username` подставлено `anna`". Это значение сохраняется в `req.params`.
|
- Когда кто-то заходит на `/user/anna`, Express видит `:username` в маршруте и понимает: "вместо `:username` подставлено `anna`". Это значение сохраняется в `req.params`.
|
||||||
|
|
||||||
|
### **Теория: Динамическая маршрутизация и извлечение данных**
|
||||||
|
Параметры пути превращают статический маршрут в шаблон, способный обрабатывать множество разных запросов. Синтаксис `:parameterName` указывает Express, что на этой позиции в URL может находиться любое значение. Express автоматически извлекает это значение из URL и помещает его в объект `req.params` под соответствующим ключом. Это основной механизм для создания RESTful API, где URL идентифицирует ресурс (например, `/users/123` идентифицирует пользователя с ID 123). Проверка `isNaN(input)` необходима, потому что параметры из URL всегда приходят в виде строк. Даже если в URL было `/double/7`, в `req.params.number` попадёт строка `"7"`. `parseFloat()` преобразует строку в число, а `isNaN()` проверяет, удалось ли это преобразование. Это защищает ваш API от некорректных данных и предотвращает ошибки выполнения.
|
||||||
|
|
||||||
### **Примеры разных параметров**:
|
### **Примеры разных параметров**:
|
||||||
|
|
||||||
1. **Один параметр**:
|
1. **Один параметр**:
|
||||||
@@ -294,6 +366,9 @@ app.get('/double/:number', function(req, res) {
|
|||||||
|
|
||||||
### **Цель задания**: Создать простой калькулятор, который принимает числа в URL и возвращает текстовый результат.
|
### **Цель задания**: Создать простой калькулятор, который принимает числа в URL и возвращает текстовый результат.
|
||||||
|
|
||||||
|
### **Теория: Построение функциональных API-эндпоинтов**
|
||||||
|
Это задание демонстрирует, как проектировать специализированные конечные точки (endpoints) API. Префикс `/api/calc/` создаёт пространство имён для всех операций калькулятора, что соответствует хорошей практике организации API. Каждая математическая операция получает собственный маршрут с чётко определёнными входными параметрами (`:a` и `:b`). Это делает API предсказуемым и удобным для использования. Возврат результата в виде простой текстовой строки с полным выражением (`5 + 3 = 8`) даёт пользователю API не только ответ, но и контекст, подтверждая, какая операция была выполнена и с какими числами. Такой подход облегчает отладку и интеграцию. Преобразование параметров из строк в числа с помощью `parseFloat()` необходимо для выполнения математических операций, так как все данные из URL изначально являются строками.
|
||||||
|
|
||||||
### **Задание**:
|
### **Задание**:
|
||||||
Создайте 4 маршрута для основных математических операций. Формат ответа — обычный текст.
|
Создайте 4 маршрута для основных математических операций. Формат ответа — обычный текст.
|
||||||
|
|
||||||
@@ -330,6 +405,9 @@ app.get('/double/:number', function(req, res) {
|
|||||||
|
|
||||||
### **Цель урока**: Добавить минимальную проверку входных данных.
|
### **Цель урока**: Добавить минимальную проверку входных данных.
|
||||||
|
|
||||||
|
### **Теория: Валидация входных данных в API**
|
||||||
|
Любой API, который принимает данные от пользователя, должен проверять их корректность перед обработкой. Это называется валидацией. Без валидации некорректные данные (например, текст вместо числа) могут вызвать ошибку в логике программы (`NaN` в математических операциях) или даже привести к падению сервера. Проверка `isNaN(a) || isNaN(b)` выявляет случаи, когда преобразование строки в число не удалось. Важно использовать `return res.status(400).send(...)` после отправки ошибки. Ключевое слово `return` гарантирует, что выполнение функции обработчика немедленно прекратится после отправки ответа с ошибкой. Без `return` код продолжил бы выполняться, пытаясь произвести вычисления с некорректными данными, что привело бы к внутренней ошибке сервера (500). Статус `400 (Bad Request)` — стандартный HTTP-код, указывающий клиенту, что проблема в присланных им данных, а не в работе сервера. Отдельная проверка деления на ноль защищает от математической ошибки, которая даст в результате `Infinity`.
|
||||||
|
|
||||||
### **Задание**:
|
### **Задание**:
|
||||||
Доработайте калькулятор из урока 9, добавив две простые проверки:
|
Доработайте калькулятор из урока 9, добавив две простые проверки:
|
||||||
|
|
||||||
@@ -387,6 +465,9 @@ if (b === 0) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### **Теория: JSON как стандарт обмена данными**
|
||||||
|
JSON стал универсальным языком для взаимодействия между различными частями веб-приложений: сервером и клиентом (браузером, мобильным приложением), а также между разными сервисами. Его главные преимущества — читаемость для человека и простота разбора для машины. В отличие от простого текста, JSON позволяет структурировать сложные данные, объединяя их в объекты с ключами и значениями, а также во вложенные списки (массивы). Метод `res.json()` в Express выполняет две важные задачи: во-первых, он преобразует переданный ему JavaScript-объект или массив в корректную JSON-строку; во-вторых, он автоматически устанавливает HTTP-заголовок ответа `Content-Type: application/json`. Этот заголовок сообщает клиенту, что в ответе пришли структурированные данные в формате JSON, которые нужно соответствующим образом интерпретировать, а не отображать как простой текст. Возврат ошибок также в формате JSON (`res.status(400).json(...)`) делает API последовательным: клиент всегда ожидает получить JSON и может единообразно обрабатывать как успешные ответы, так и ошибки.
|
||||||
|
|
||||||
### **Практическое задание**:
|
### **Практическое задание**:
|
||||||
1. Создайте маршрут `GET /api/user/:id`
|
1. Создайте маршрут `GET /api/user/:id`
|
||||||
2. Если `:id` — число, верните JSON с информацией о пользователе:
|
2. Если `:id` — число, верните JSON с информацией о пользователе:
|
||||||
@@ -428,6 +509,9 @@ app.get('/api/user/:id', function(req, res) {
|
|||||||
|
|
||||||
### **Цель урока**: Переделать текстовый калькулятор для возврата JSON.
|
### **Цель урока**: Переделать текстовый калькулятор для возврата JSON.
|
||||||
|
|
||||||
|
### **Теория: Проектирование структуры JSON-ответов**
|
||||||
|
Структурированный JSON-ответ должен быть информативным и машиночитаемым. Введение поля `success: true/false` позволяет клиенту быстро определить, был ли запрос успешным, без необходимости анализировать HTTP-статус код или содержимое ответа. Поле `operation` явно указывает, какая операция была выполнена, что полезно при логировании и отладке. Объект `arguments` дублирует исходные данные, предоставляя контекст. Поле `result` содержит итог вычислений. В случае ошибки вместо данных результата возвращается объект `error` с детализацией. Поле `code` (например, `"DIVISION_BY_ZERO"`) — это машинно-читаемый код ошибки, по которому клиентское приложение может выполнить конкретное действие (например, показать определённое сообщение). Поле `message` содержит человекочитаемое описание. Такой подход соответствует лучшим практикам проектирования REST API, делая его предсказуемым и удобным для интеграции.
|
||||||
|
|
||||||
### **Задание**:
|
### **Задание**:
|
||||||
Измените все 4 операции калькулятора так, чтобы они возвращали данные в JSON-формате.
|
Измените все 4 операции калькулятора так, чтобы они возвращали данные в JSON-формате.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user