diff --git a/docs/pages/docs/architecture-and-structures/Backend API communication/Readme.md b/docs/pages/docs/architecture-and-structures/Backend API communication/Readme.md index 6d97178ae..aa9ed3d75 100644 --- a/docs/pages/docs/architecture-and-structures/Backend API communication/Readme.md +++ b/docs/pages/docs/architecture-and-structures/Backend API communication/Readme.md @@ -1,24 +1,64 @@ # Backend API Communication +Тут ми розглянемо з теоретичної сторони, як комунікувати з бекендом у апплікейшенах. + +### Чому одночасно Webitel SDK та Raw Endpoints? + +Так склалось історично, але, сподіваюсь, колись це пройде і будуть тільки Webitel SDK ендпоінти. + ## Webitel SDK Endpoints +Webitel SDK ендпоінти - це ендпоінти, згенеровані автоматично через Open API (aka Swagger). + +Відповідно, замість того щоб самостійно будувати `url`, і все таке - ми просто передаємо параметри +у методи, які нам дає бібліотека, згідно певної сутності. Список цих сутностей та ендпоінтів можна +подивитись на [webitel swager](https://swagger.webitel.com/#/)'i. + +З запитами, які мутують дані, все просто: `body` виглядає стандартно. А от з `search` ендпоінтами складнощі, +бо генерування api налаштоване так, що параметри необхідно передавати по порядку, а не одним обʼєктом. + +Тобто, замість + +```javascript +service.searchSmth({ page, size, search }); +``` + +нам треба робити ось так + +```javascript +service.searchSmth(page, size, search); +``` + +а отже, відповідно, **порядок параметрів має значення**. + +Також у `service` з api методами, які ми створюємо, можна (і потрібно!) передати наш `axios instance`, +отже, всі інтерцептори і хедери, застосовувані в ньому, будуть застосовані також. + ## Raw Endpoints +Тут все доволі безхитрісно і типово: ми маємо `axios instance`, ми маємо `baseUrl` групи ендпоінтів по певній +сутності, і, ми просто формуємо `url` запиту, його `body` - та й все. + +Проблема в тому, що ці ендпоінти не описані у сваггері, а отже, інформація про них передається традиційно: +із уст в уста. 🫠 + ## Тонкощі роботи з ендпоінтами ### Falsy values -API Gateway на бекенді налаштований так, що не вертає полів, які мають falsy значення. +**API** Gateway на бекенді налаштований так, що **не вертає полів, які мають falsy значення**. А нам-то ці поля потрібні! -Отже, ми маємо в ці поля сетати дефолтні для них значення. +Отже, ми **маємо в ці поля сетати дефолтні для них значення**. -### Чому одночасно Webitel SDK та Raw Endpoints? +## WebSocket -Так склалось історично, але, сподіваюсь, колись це пройде і будуть тільки Webitel SDK ендпоінти. +Для організації роботи з дзвінками або чатами використовується WebSocket зʼєднання. -## WebSocket +Як правило, на Webitel SDK WebSocket'i (вебсокет обгорнутий у бібліотеку, яка має методи керування ним) +працює Workspace та Supervisor. А Omni-widget - на raw WebSocket'i +(створюємо і відкриваємо коннекшен самостійно). ## А як додать апішку-то? diff --git a/docs/pages/docs/how-to/add-a-REST-API-module/Readme.md b/docs/pages/docs/how-to/add-a-REST-API-module/Readme.md index f01306457..7cdd913ca 100644 --- a/docs/pages/docs/how-to/add-a-REST-API-module/Readme.md +++ b/docs/pages/docs/how-to/add-a-REST-API-module/Readme.md @@ -15,10 +15,95 @@ - axios interceptors: [api/interceptors](../../../webitel-ui/api/interceptors/Readme.md) - Трансформери для даних: [api/transformers](../../../webitel-ui/api/transformers/Readme.md) +### REST API Module Interface + +**Обовʼязково, подивіться у секцію Interface [api/clients](../../../webitel-ui/api/clients/Readme.md#interface).** + ## Як додати Webitel SDK Endpoint модуль? +### TLDR; Піддивіться у souce code якогось з `api/clients` 🙂 +### Довгий та розумний шлях + +Спершу, нам треба створити `service` з `ApiFactory`, наприклад + +```javascript +import { SomeEntityApiFactory } from 'webitel-sdk'; + +const service = new SomeEntityApiFactory(instance, '', openAPIConfig); +``` + +Далі, у нас є вхідні параметри, які ми передаємо у метод апі модуля. + +Це може бути `params`, `itemInstance`, `changes`, чи ше шось (знов таки, дивіться у [інтерфейси](#rest-api-module-interface)) + +Нам треба ці параметри якось "обробити", підготувати до відправки. + +Для цього у нас є трансформери, в `api/transformers`. Вони, як пайплайн, обробляють вхідні параметри, +і повертають оброблені. + +Що нам зазвичай треба обробити? + +(1) Як правило, перевести дані з того, що піде як `body` у snake_case з camelCase. + +(2) Почистити непотрібні поля, адже бекенд їх не прийме і викине помилку. + +(3) Зробити якісь кастомні трансформації з даними, специфічні саме для цього ендпоінта. + +Як це виглядає? + +```javascript +const addItem = ({ itemInstance }) => { + + const body = applyTransform(itemInstance, [ + camelToSnake, // (1) + sanitize(fieldsToSend), // (2) + ({ id, ...rest }) => ({ + itemId: id, + ...rest + }), // (3) + ]); +} +``` + +Далі, ми викликаємо наш api метод + +```javascript +const addItem = async ({ itemInstance }) => { + // ... + + const response = await service.add(body); +} +``` + +Обробляємо відповідь, наприклад, дописуючи `counter: 0` + +```javascript +() => { + // ... + + const item = applyTransform(response, [ + (item) => ({ ...item, counter: 0 }), + ]); +} +``` + +Ну і, обробляєм потенційну помилку + +```javascript +() => { + // ... + try { + // ... + } catch (err) { + throw applyTransform(err, [ + log, + ]); + } +} +``` + ### Тонкощі #### Як знайти необхідну мені ApiFactory, та її методи? @@ -38,7 +123,25 @@ Де замість `...` - назва сутності, з якою ми працюємо. ## Як додати Raw Endpoint модуль? + +Та в принципі, те саме що і з Webitel SDK ендпоінтом, тільки тут нам треба сформувати `url`, +щоби зробити на нього запит, як + +```javascript +const baseUrl = '/entity'; + +async (id) => { + // ... + + const url = `${baseUrl}/${id}`; + const response = await instance.get(url); +} +``` + +### TLDR; Піддивіться у souce code якогось з `api/clients` 🙂 +### Довгий та розумний шлях + ### Тонкощі Тут - немає. Берете, формуєте `url`'ку, викликаєте http метод, обробляєте відповідь.