Files
intprog/lwF4/README.md

242 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Лабораторная работа №F4 - Взаимодействие с API (Axios)
## Цель работы
- Освоение взаимодействия между fronend и backend в веб-приложениями посредством технологии `axios`.
- Получение навыков формирования макета RESTful API при помощи технологии `json-server`.
- Освоение технологии `Postman` для работы с API, основанным на протоколе HTTP(S).
## Ход работы
1. Проверить и при необходимости исправить код описания формы ввода данных в приложении из [lwF3](../lwF3/README.md).
2. Развернуть API-сервер на основе `json-server` рядом с frontend-приложением.
3. Развернуть ПО Postman и выполнить CRUD-запросы на API-сервере (backend).
4. Подключить к frontend пакет `axios`.
5. Добавить в обработчик отправки формы вызов метода добавления данных в API-сервер при помощи axios.
6. Убедиться через Postman и через блокнот, что данные корректно пришли с frontend на backend.
## Проверка формы ввода
При использовании Consta Design, убедитесь, что все текстовые поля записывают значение во внутреннее состояние формы.
Если используете собственные обёртки, пропсы `value` и `onChange` "перекидывать" из компонентов Consta Design далее.
Пример формы БЕЗ компонентов-обёрток (у Вас должно быть с "обёртками"):
```tsx
export const FeedbackForm = () => {
const [nameValue, setNameValue] = useState<string | null>(null);
const [textValue, setTextValue] = useState<string | null>(null);
const handleSend = () => {
/* TODO: логика по отправке данных на сервер. */
};
return (
<Theme preset={presetGpnDefault}>
<TextField
onChange={setNameValue}
value={nameValue}
type="text"
label="Имя"
placeholder="Как Вас зовут?"
/>
<TextField
onChange={setTextValue}
value={textValue}
type="textarea"
rows={5}
label="Сообщение"
placeholder="Напишите, что Вы думаете о нас..."
/>
<Button label="Отправить" onClick={handleSend} />
</Theme>
);
}
```
Пример обёртки над текстовым полем:
```jsx
import {
TextField as ConstaTextField,
TextFieldPropOnChange,
TextFieldPropValue,
} from "@consta/uikit/TextField";
interface TextFieldProps {
onChange: TextFieldPropOnChange;
value: TextFieldPropValue;
label: string;
placeholder: string;
}
export const TextField = (props: TextFieldProps) => (
<ConstaTextField
type="text"
onChange={props.onChange}
value={props.value}
label={props.label}
placeholder={props.placeholder}
/>
);
```
Если же вы используете обычные элементы `input`, `textarea` и т.п., тогда надо использовать их в controlled-режиме (подробнее о режимах полей ввода [можете почитать в документации](https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable)).
Например, так:
```jsx
<input
onChange={(e) => setNameValue(e.target.value)}
value={nameValue}
type="text"
placeholder="Как Вас зовут?"
/>
<textarea
value={textValue}
onChange={(e) => setTextValue(e.target.value)}
placeholder="Напишите, что Вы думаете о нас..."
></textarea>
```
Только обратите внимание, что необходимо изменить тип в переменных состояния, отвечающих за значения данных на форме, т.к. `string | null` уже не подходит.
## Установка сервера json-server
Создайте каталог рядом с react-приложением.
Создайте в нём файл `db.json` с содержимым:
```json
{
"feedback": []
}
```
> Замените `feedback` на кодовое название сущности, к которой относится ваша форма.
> Например, `order` для заказа, `thread` для ветви обсуждения и т.п.
Запустите в консоли в созданном каталоге команду `npx json-server db.json`.
Примерный вывод:
```
JSON Server started on PORT :3000
Press CTRL-C to stop
Watching db.json...
♡( ◡‿◡ )
Index:
http://localhost:3000/
Static files:
Serving ./public directory if it exists
Endpoints:
No endpoints found, try adding some data to db.json
Endpoints:
http://localhost:3000/feedback
```
Запомните последнюю ссылку, она нам понадобится позже.
## Проверка работы API при помощи утилиты Postman
Postman утилита для работы с API-интерфейсами в стиле REST (популярен в web).
Страница для скачивания: <https://www.postman.com/downloads/>.
Продолжите запуск без учётной записи (2 раза надо об этом сказать).
Далее необходимо сделать процедуры CRUD.
Это сокращение от Create, Read, Update, Delete.
Согласно документации json-server доступны следующие методы API (на примере ресурса `posts`):
```
GET /posts
GET /posts/:id
POST /posts
PUT /posts/:id
PATCH /posts/:id
DELETE /posts/:id
```
Попробуем выполнить запросы по аналогии с feedback.
Создание:
![](postman_post.png)
Просмотр списка:
![](postman_get_all.png)
Просмотр подробностей:
![](postman_get.png)
Обновление:
![](postman_put.png)
Удаление:
![](postman_delete.png)
При этом в файле `db.json` всё время будут происходить изменения, инициированные запросами к API.
## Подключение axios к frontend
Axios технология для вызова API-методов (по аналогии с Postman) для frontend-приложений.
Устанавливается при помощи команды `npm install axios`.
Использовать axios необходимо в функции `handleSend`.
Сделайте это самостоятельно, используя следующие требования/подсказки:
- Метод `handleSend` удобно поментить `async`.
В этом случае вызов `post(endpont, data)` из библиотеки `axios` можно пометить как `await`.
- Собирать объект для отправки на бекенд надо прямо в методе `.post`, а не через отдельную контанту/переменную.
- При ошибке (например, сервер недоступен) метод `axios.post` выбрасывает исключение.
Его надо ловить и каким-то образом показывать на экран.
Для этого можно использовать функцию `alert` или ошибку из пакета `react-toastify` (ставится отдельно).
- В случае успеха надо также использовать отображение данных через `alert` или `toast`.
- Метод не должен ничего выводить в консоль. Только для отладки. Код вывода в консоль перед сдачей лабораторной работы должен быть удалён.
Пример отправки данных на сервер, который НЕ подходит под требования, но который работает:
```jsx
import axios from "axios";
const handleSend = () => {
console.log(nameValue, textValue);
const data = {
name: nameValue,
text: textValue,
};
axios
.post("http://localhost:3000/feedback", data)
.then(() => alert("Данные отправлены, спасибо!"));
};
```
## Проверка работы
Убедитесь, что после отправки формы в файле `db.json` появляются указанные в полях ввода данные.
Дополнительно убедитесь, что через Postman в методе GET также возвращаются эти же данные.
Убедитесь, что при отключении json-server приложение React начинает выдавать ошибку отправки, правда спустя какое-то время (тайм-аут).
## Дополнительные улучшения
> За которые возможны доп. баллы.
1. Вместо alert использовать react-toastify с правильно подобранными типами уведомлений: для ошибки - ошибка, для успеха - успех.
2. Необходимо на время отправки данных блокировать (disabled) кнопку отправки и поля ввода.
3. Если при отправке формы был получен успешный ответ от API, получать и выводить `id` созданной сущности.
Например, `Обращение №4ba0 зарегистрировано, спасибо!`