Salesforce є грандіозним і прагне бути універсальним інструментом та платформою для підтримки будь-якого бізнесу і діяльності.
Він містить велику кількість інструментів, хмар даних і властивостей для побудови бізнес-процесів, співпраці компаній і налаштування всього, що ви створюєте всередині Salesforce, як, наприклад, бізнес-застосунки, сайти тощо.
Коли інструментів та функцій адміністрування недостатньо, і людям потрібно щось більш специфічне, ніж готові рішення «з коробки», вони можуть використовувати нативні мови програмування Salesforce та front-end фреймворки. Це мова сервера Apex, мови баз даних SOQL та SOSL, Visualforce Pages та Lightning Components.
Але незалежно від того, що ми використовуємо, ми маємо справу з даними. Кожен крок може розглядатися як використання даних та/або управління ними.
Особливо ми маємо справу з управлінням даними під час створення коду. Під управлінням даними я маю на увазі зміну наявних даних або створення нових даних.
Запити до бази даних всередині Salesforce
Для управління даними ми беремо дані до Apex коду, який використовує дані для перетворення даних на інші дані. Це забезпечується запитами SOQL, які є запитами до бази даних. Кожен запит може містити власні фільтри та вкладені запити зі своїми фільтрами й вкладеними запитами. Вкладені запити можуть бути комбінацією логічного виразу на кшталт 1 AND 2 AND 3.
Тож у загальному випадку ми можемо уявити, що кожен обсяг запитів SOQL до бази даних може бути представлений таким чином (O# означає якийсь об’єкт Salesforce (стандартний або користувацький), FO# означає поле пошуку об’єкта O#):
Малюнок 1 – Загальна структура запитів
На малюнку 1 представлена загальна структура пакету запитів.
Тут зображено лише 2 рівні для вкладених запитів. Але насправді структура запитів може бути набагато складнішою з більшою кількістю вкладених рівнів запитів.
Крім того, вона може мати зовсім іншу булеву логіку, ніж на малюнку 2.
Малюнок 2 – Варіант структури запитів
Крім того, lookup поле та поле ID міняються місцями у запиті залежно від того, що потрібно користувачеві:
Малюнок 3 – Перестановка lookup полів всередині вкладеного запиту
Підсумуємо, що залежно від вимог бізнесу:
- може бути багато вкладених запитів до бази даних і багато рівнів вкладеності;
- запити можуть мати різноманітні булеві логіки;
- lookup поля можуть помінятися місцями з полями ID у вкладеному запиті.
Обмеження мови бази даних Salesforce SOQL
Відомо, що Salesforce SOQL може підтримувати лише один рівень вкладеності для вкладеного запиту на один запит до бази даних.
Отже, як розробник обходить це обмеження?
Найпоширенішим способом є отримання ідентифікаторів пов’язаних записів у список ідентифікаторів для використання таких списків ідентифікаторів у цільовому запиті. Це можна зробити таким чином:
Малюнок 4 – Допоміжний код для отримання пов’язаного списку ідентифікаторів записів
Коли бізнес-логіка диктує більш складні умови для вибору записів, розробник буде використовувати якийсь подібний код, як наведено вище, стільки разів, скільки потрібно.
Крім того, розробник кожного разу забезпечуватиме відповідний порядок виконання запитів згідно з булевою логікою на кожному рівні вкладеності.
І все це буде зроблено стільки разів, скільки разів будуть змінені вимоги бізнесу.
Величезні регулярні фінансові витрати на розробку
Це вимагає певних вкладень часу і грошей, більше інвестицій, якщо логіка запитів до бази даних складна. А також – набагато більше інвестицій на одноразову зміну, якщо зміни відбуваються рідко. Це відбувається тому, що розробники не завжди досить добре описують свій код, тому що у компаній немає культури підтримки проєктних документів. Ось чому зміни до раніше розробленого коду можуть бути болючими й затратними.
Саме тому рекомендується використовувати окремі класи та методи для отримання даних. Це принцип поділу логіки запитів даних і бізнес-логіки.
Але все ж розробка коду для запитів даних потрібна, і на це потрібні час і гроші.
Рішення, яке зберігає кошти (синхронний код)
Саме тому може бути вигідно пропустити розробку коду для запиту даних, працюючи тільки за бізнес-логікою.
Для цього я розробив Query Manager, який є універсальним інструментом для ізоляції запитів даних та коду бізнес-логіки.
Він складається з контролера запитів, UI конструктора запитів та об’єкта збереження параметрів запитів.
Конструктор запитів призначений для налаштування параметрів запитів та фільтрації.
Контролер запитів використовує збережені параметри запитів та фільтрації для отримання даних і передачі даних до коду бізнес-логіки клієнта.
Об’єкт збереження параметрів запитів – це об’єкт, записи якого зберігають налаштування запитів та фільтрації, і ці записи використовуються для роботи контролера запитів.
Query Manager дає змогу сконцентруватися на розробці та підтримці лише бізнес-логіки незалежно від змін логіки запитів даних.
Це шлях для економії грошей багатьма способами:
- Ви не витрачаєте багато часу на дослідження наявного коду, який слугує для отримання даних.
- Ви не витрачаєте багато часу на оновлення коду для отримання даних.
- Ви не витрачаєте час на тестування оновлень та деплой оновлень на продакшені.
- Ви можете підтримувати робочі процеси, розкриваючи цілі та залишаючи коментарі прямо у спеціальних полях записів параметрів запитів. Також можна відстежувати дату останніх оновлень у логіці запитів і так далі.
Query Manager має два глобальних методи, які доступні для синхронного Apex. Це такі методи:
@AuraEnabled global static String getPagedRecordsForApex (String dataTableSettingsId, integer pgNum, integer pgSize):
@AuraEnabled global static List <SObject> getAllRecordsForApex (String dataTableSettingsId)
Метод getPagedRecordsForApex повертає записи як рядок для певної сторінки пагінації даних.
Метод getAllRecordsForApex повертає всі записи, які доступні відповідно до збережених параметрів запитів та фільтрації.
Докладніше про те, як використовувати ці методи, дивіться у відео.
Допоміжні Batchable класи
Дехто може сказати: добре, ви надали рішення для синхронного Apex, але як щодо асинхронних класів Batchable?
Питання порушено тому, що розробники використовують класи Batchable для роботи з великим обсягом записів через обмеження Salesforce для SOQL (50 тисяч записів за транзакцію) операцій і для операцій DML (10 тисяч записів за одну транзакцію).
Іноді в таких випадках з’являються допоміжні класи Batchable. Під допоміжними класами я маю на увазі ті, які виконують ту ж роль, що і код на малюнку 4 (допоміжний код для отримання відповідних ідентифікаторів записів).
Але на протиставлення синхронному Apex, де може бути використаний окремий метод, в асинхронному Apex необхідно використовувати додатковий окремий Batchable клас.
Оскільки логіка запитів може бути складною і може змінюватися для різних процесів всередині організації, розробники повинні запроваджувати стільки Batchable класів, скільки потрібно для цих процесів, пов’язуючи їх кожного разу у потрібній послідовності згідно з логікою запитів потрібних даних.
І знову це вимагає певних вкладень часу і грошей. Навіть більших, аніж для синхронного коду.
Рішення, яке зберігає кошти (асинхронний код)
Так само, як для синхронного Apex, є рішення для асинхронного коду, яке економить ваші гроші, пропускаючи розробку допоміжних Batchable класів за допомогою Query Manager.
З цією метою Query Manager має глобальний метод static void callByFilteringSettings (String className, String settingsId).
З цим методом ви можете пропустити всі допоміжні Batchable класи й отримати результат запитів до бази даних прямо у ваш цільовий Batchable клас із вашою індивідуальною логікою.
Докладніше про те, як використовувати метод callByFilteringSettings, дивіться у відео.
Фундаментальні невирішені проблеми
Попри те, що ми отримали принципово новий підхід до розробки, все ще залишаються деякі невирішені ключові проблеми.
Перша проблема полягає в тому, що для синхронного Apex все ще залишається ліміт у 50 тисяч записів для всіх SOQL запитів у межах однієї транзакції, а саме в ціх межах існує виконання синхронного коду. І, мабуть, ми нічого не можемо з цим вдіяти. Єдине, чим ми можемо дещо поліпшити продуктивність, так це застосуванням мого рішення для нескінченної пагінації сторінок, яка була описана у моїй іншій статті. І це один із пунктів вдосконалення у майбутньому.
Друга проблема – це heap size та CPU Time лімітів для асинхронного коду (для класів Batchable).
Це питання можна вирішити двома підходами. Перший заснований на розробці кодера і декодера ідентифікаторів записів. Цей кодер та декодер повинні приймати перший ідентифікатор, останній ідентифікатор, принцип впорядкування між першим та останнім ідентифікаторами й назву SObject-а. Але наразі я не знаю технічного рішення для такого підходу. Будь ласка, запропонуйте, яким може бути рішення.
Другий підхід полягає у використанні файлів CSV з ідентифікаторами для допоміжних класів Batchable. Це більш зрозуміло і може допомогти у вирішенні heap size та CPU Time лімітів.
Отже, друге питання також є пунктом вдосконалення у майбутньому.
Обмеження і недоліки, які наявні на цьому етапі:
- Немає обробки перевищення лімітів SOQL та інших лімітів. У деяких випадках це може бути незручно. Це також пункт для вдосконалення у майбутньому.
- Тільки SObjects, які користувач може бачити в Object Manager всередині організації, доступні в Query Manager. Це зроблено з метою не перевантажувати користувачів і розробників додатковою інформацією в інтерфейсі Query Builder. Доступ до всіх об’єктів можна зробити для окремої розширеної версії.
- Менеджер запитів взагалі не тестувався з Queable Classes. Це точка для майбутнього розслідування і вдосконалення.
- Концепція управління запитами для управління розробкою та підтримкою проєкту. На цей момент вказана концепція не до кінця оформлена в могутню філософію розробки.
- Таблиці даних із різними функціональними можливостями й адаптивні для користувацької функціональності, які трансформуються на будь-який смак користувача. Це також пункт для вдосконалення у майбутньому.
- Деякі інші недоліки та помилки, які ви можете знайти, використовуючи Query Manager.
Висновки
Query Manager – це зручний, перспективний і трансформаційний продукт та філософія.
Він безкоштовний.
Основна мета створення і розвитку – отримання корисних та економних концептів.
Ваше використання та відгуки – дуже приємні та важливі інвестиції. Тому моя пропозиція для бізнесу та розробників – використовувати Query Manager.
Підписуйтеся на ProIT у Telegram, щоб не пропустити жодну публікацію!