Задание: Получение и отправка задач
#
Задание#
Функції для роботи з APIМає бути чітке розділення між роботою з API та маніпуляціями з DOM. Кожен запит до API повинен
- знаходитись в окремій функції
- функція повертає
Promise
з даними (тілом відповіді) в якості результату - функція нічого "не знає" про структуру елементів на сторінці
4xx
та5xx
помилки мають призводити до результату зі статусомrejected
#
Оновлення UI даними з сервераПройде деякий час між тим як:
- користувач натисне кнопку "Додати задачу"
- задача фактично з'явиться в базі даних на сервері а клієнт дізнається з відповіді серверу ID новоствореної задачі.
Запит, відправлений на сервер, виконується асинхронно. Технічно, відповідь від сервера, якими б швидкими не були інтернет та сервер, буде вже оброблюватися в іншій "ітерації обробки подій" (дивись про Event Loop в браузері). Синхронна частина обробника події кліку по кнопці "Додати задачу" завершиться раніше, ніж ми отримаємо відповідь від серверу та дізнаємось ID нової задачі.
Але, при цьому, нам потрібно:
- Якось інформувати користувача про те, що ми "побачили" клік по кнопці і відреагували на нього.
- Сповістити користувача про результат операції на сервері. Успішний або помилку.
Умовно, для кращого розуміння, розділимо обробку кліку по кнопці "Додати задачу" на дві фази:
- Синхронна
- збираємо данні з форми в об'єкт задачі
- перевіряємо, чи вказана назва задачі
- відправляємо нову задачу в тілі запиту на сервер
- Асинхронна
- отримаємо відповідь від серверу
- перевіряємо статус код відповіді
- записуємо отриманий ID нової задачі
У списку вище жодна з фаз не містить один ключовий крок: показати на сторінці новостворену задачу. Фаза, на якій ми будемо це робити, визначає підхід до реакції інтерфейсу на дії користувача. Відповідно, маємо два підходи, коли оновлювати UI:
- Оптимістичний UI - додаємо задачу в список на сторінці в синхронній фазі
- Песимістичний UI - оновлюємо сторінку асинхронно, після отримання успішної відповіді від серверу
#
Оптимістичний UIПеревага для користувача:
- Моментальна реакція на його дії. В користувача складається враження, наче він працює з локальним додатком.
Складніший в реалізації:
- У випадку помилки мережі чи на сервері необхідно ще раз оновити сторінку. Треба якось виділити фактично не створену задачу і дати користувачу інтерфейс для ще одної спроби.
- При успішній відповіді від серверу необхідно ще раз оновити локальне сховище та записати туди cгенеровний для задачі ID
Типові приклади - системи реального часу:
- Чати. Повідомлення може не зберегтись, тільки якщо сервер впав чи нема мережі
- Онлайн редактори. Всі зміни в доках, таблицях та графічних редакторах зберігаються в фоні
#
Песимістичний UIНедоліки для користувача:
- Відчуття затримки та розірваності між діями та реакцією системи
- Ускладнює швидку роботу, коли потрібно створити декілька сутностей поспіль
Простіший в реалізації:
- Показуємо спінер, поки не прийде відповідь від сервера
- Як тільки отримали відповідь - ховаємо спінер. Додаємо створену задачу чи показуємо помилку
- Локальне сховище оновлюється лише 1 раз
Типові приклади - системи автоматизації бізнес процесів, фінансові системи. Загалом, будь які системи, де надійність та достовірність важливіші за швидкодію та користувацький досвід. В таких системах нерідко на стороні серверу є чимало перевірок, які можуть запобігти успішній обробці запиту.
Приклади перевірок, які можуть бути на сервері:
- В HR системах ...
- перетин по датах заяви на відсутність з раніше поданими заявами
- недостатня кількість нарахованих днів для відпочинку
- відсутність дозволу в залогіненого користувача виконати операцію
- В фінансових системах ...
- недостатня кількість грошей на рахунку
- перевищення лімітів
#
Про локальне сховищеВ якості локального сховища можуть виступати різні компоненти додатку:
- Самі DOM елементи на сторінці та їх
data-
атрибути - Масив з даними просто в JavaScript коді
- Стан компоненту UI бібліотеки (наприклад
React.useState
) - Глобальне сховище стану по типу Redux