Підручник з Salesforce Apex для початківців

⚡ Розумний підсумок

Програмування Apex надає розробникам Salesforce об'єктно-орієнтовану мову строго типізованих програм для додавання власної бізнес-логіки до CRM. Вона забезпечує класи, тригери та пакетні завдання, тоді як обмеження регуляторів підтримують стабільність спільної багатокористувацької платформи.

  • 🧱 Foundation: Apex — це мова, яка не враховує регістр літер. Java-подібний синтаксис, який працює нативно на платформі Salesforce Lightning.
  • 🗃️ Доступ до даних: Запити SOQL та оператори DML дозволяють вашому коду зчитувати та записувати записи sObject безпосередньо в базу даних Salesforce.
  • 🛠️ Реалізація: Класи, властивості та тригери додають власну логіку до вставки, оновлення, видалення та інших системних подій записів.
  • 📦 Масштаб: Batch Apex та інші асинхронні опції обробляють мільйони записів фрагментами, не порушуючи обмежень платформи.
  • 🚦 Обмеження губернатора: Обмеження на транзакцію, такі як 100 синхронних SOQL-запитів та 150 DML-інструкцій, захищають спільні ресурси.
  • Якість: Модульні тести повинні охоплювати щонайменше 75 відсотків коду Apex перед розгортанням у робочому середовищі.

Огляд програмування APEX Salesforce

Що таке Apex у Salesforce?

Вершина — це об'єктно-орієнтована мова програмування зі строгою типізацією, розроблена Salesforce для створення програмного забезпечення як послуги (SaaS) та програм для управління взаємовідносинами з клієнтами (CRM). Apex допомагає розробникам створювати сторонні SaaS-програми та додавати бізнес-логіку до системних подій, забезпечуючи підтримку серверних баз даних та клієнт-серверні інтерфейси.

Apex допомагає розробникам додавати бізнес-логіку до системних подій, таких як натискання кнопок, оновлення пов’язаних записів та сторінки Visualforce. Apex має синтаксис, подібний до Java. Зареєструйтеся в Salesforce щоб дізнатися, як працює CRM.

Особливості мови програмування Apex

Ось важливі функції Salesforce Apex:

  • Apex — це мова, яка не враховує регістр літер.
  • Ви можете виконувати операції DML, такі як INSERT, UPDATE, UPSERT та DELETE, над записами sObject за допомогою Apex.
  • Ви можете запитувати записи sObject за допомогою SOQL (Salesforce Object Query Language) та SOSL (Salesforce Object Search Language) в Apex.
  • Дозволяє створювати a одиничне випробування і виконайте його, щоб перевірити покриття коду та ефективність коду в Apex.
  • Apex працює в середовищі з кількома клієнтами Salesforce має визначені обмеження регуляторів, які запобігають монополізуванню користувачем спільних ресурсів. Будь-який код, який перевищує обмеження регулятора Salesforce, завершується невдачею, і з'являється повідомлення про помилку.
  • Об'єкт Salesforce можна використовувати як тип даних в Apex. Наприклад:
    Account acc = new Account();

    Тут Account – це стандартний об’єкт Salesforce.

  • Apex автоматично оновлюється з кожним випуском Salesforce.

Коли розробнику варто обрати Apex?

Код Apex слід писати лише тоді, коли бізнес-сценарій занадто складний для реалізації за допомогою попередньо вбудованої функції «вкажи та клацни», що надається Salesforce.

Нижче наведено кілька сценаріїв, у яких вам потрібно написати код Apex:

  • Щоб створити веб-сервіси, які інтегрують Salesforce з іншими програмами.
  • Реалізувати власну валідацію на sObjects.
  • Виконувати власну логіку Apex під час виконання операції DML.
  • Для реалізації функціональності, яку неможливо створити за допомогою існуючих декларативних інструментів автоматизації, таких як Flow.
  • Встановлювати послуги електронної пошти що обробляють вміст, заголовки та вкладення вхідної електронної пошти.

Щойно ви зрозумієте, коли Apex — правильний вибір, наступним кроком буде розуміння того, що відбувається з вашим кодом після його збереження.

Робоча структура Apex

Нижче наведено послідовність дій для коду Apex:

  • Дія розробника: Коли розробник зберігає код на платформі, весь код Apex компілюється в набір інструкцій, які може зрозуміти інтерпретатор середовища виконання Apex, а потім ці інструкції зберігаються як метадані на платформі.
  • Дія кінцевого користувача: Коли подія користувача виконує код Apex, сервер платформи отримує скомпільовані інструкції з метаданих та пропускає їх через інтерпретатор Apex, перш ніж повернути результат.

На діаграмі нижче показано, як дії розробника та кінцевого користувача взаємодіють із сервером застосунків Lightning Platform:

Робоча структура Apex

Середовище розробки Apex

Код Apex можна розробляти або в ізольованому середовищі, або в організації Salesforce Developer Edition.

Найкращою практикою є розробка коду в ізольованому середовищі, а потім розгортання його у робочому середовищі, як показано нижче:

Середовище розробки Apex

Інструменти розробки коду Apex: Нижче наведено три інструменти, доступні для розробки коду Apex у всіх версіях Salesforce:

  • Консоль розробника
  • Visual Studio Code з пакетом розширень Salesforce (він замінює списану IDE Force.com)
  • Code редактор у інтерфейсі користувача налаштування Salesforce

Коли ваше середовище готове, давайте розглянемо основні елементи самої мови, починаючи з типів даних.

Типи даних в Apex

Apex підтримує такі типи даних:

примітив

ціле число, Double, Long, Date, Datetime, Decimal, Time, Blob, String, ID та Boolean вважаються примітивними типами даних. Усі примітивні типи даних передаються за значенням, а не за посиланням.

Колекції

В Apex доступні три типи колекцій:

  • список: Це впорядкована колекція примітивів, sObjects, колекцій або об'єктів Apex на основі індексів.
  • Комплект: Невпорядкована колекція унікальних елементів, яка не містить дублікатів.
  • Карта: Це колекція унікальних ключів, які відповідають окремим значенням, що можуть бути примітивами, sObjects, колекціями або об'єктами Apex.

sObject

Це особливий тип даних у Salesforce. Він схожий на таблицю в SQL і містить поля, подібні до стовпців у SQL.

Переліки

Перелік — це абсtracТип даних t, який зберігає одне значення скінченного набору заданих ідентифікаторів.

Класи, об'єкти та інтерфейси

Визначені користувачем класи та інтерфейси Apex також можуть використовуватися як типи даних. Об'єкт посилається на екземпляр будь-якого типу даних, що підтримується в Apex.

Синтаксис Apex

Декларація змінних

Оскільки Apex є строго типізованою мовою, обов'язково оголошувати змінну з типом даних в Apex.

Наприклад:

Contact con = new Contact();

Тут змінна con оголошується з типом даних Contact.

Запит SOQL

SOQL розшифровується як мова запитів об'єктів Salesforce. SOQL використовується для отримання записів sObject з бази даних Salesforce. Наприклад:

Account acc = [SELECT Id, Name FROM Account LIMIT 1];

Наведений вище запит отримує запис облікового запису з бази даних Salesforce.

Оператор циклу

Оператор циклу використовується для перебору записів у списку. Кількість ітерацій дорівнює кількості записів у списку. Наприклад:

List<Account> listOfAccounts = [SELECT Id, Name FROM Account LIMIT 100];
// iteration over the list of accounts
for(Account acc : listOfAccounts){
	//your logic
}

У наведеному вище фрагменті коду listOfAccounts – це змінна типу даних List.

Заява про керування потоком

Оператор керування потоком корисний, коли потрібно виконати кілька рядків коду на основі певних умов.

Наприклад:

List<Account> listOfAccounts = [SELECT Id, Name FROM Account LIMIT 100];
// execute the logic if the size of the account list is greater than zero
if(listOfAccounts.size() > 0){
	//your logic
}

Наведений вище фрагмент коду запитує записи облікових записів з бази даних та перевіряє розмір списку.

Заява DML

DML розшифровується як мова маніпулювання даними (Data Manipulation Language). Оператори DML використовуються для маніпулювання даними в базі даних Salesforce. Наприклад:

Account acc = new Account(Name = 'Test Account');
insert acc; //DML statement to create account record.

Специфікатори доступу Apex

Нижче наведено специфікатори доступу, що підтримуються Apex:

громадськості

Цей специфікатор доступу надає доступ до класу, методу або змінної, що використовуються Apex у просторі імен.

приватний

Цей специфікатор доступу надає доступ до класу, методу або змінної, які будуть використовуватися локально або в розділі коду, де вони визначені. Усі методи та змінні, для яких не визначено специфікатор доступу, використовують специфікатор доступу за замовчуванням private.

захищений

Цей специфікатор доступу надає доступ до методу або змінної, яка буде використовуватися будь-якими внутрішніми класами в межах визначального класу Apex.

Глобальний

Цей специфікатор доступу надає доступ до класу, методу або змінної, які будуть використовуватися Apex як у просторі імен, так і поза ним. Рекомендується не використовувати ключове слово global, якщо в цьому немає необхідності.

Ключові слова в Apex

З поділом

Якщо клас визначено за допомогою цього ключового слова, то застосовуються всі правила спільного доступу, що застосовуються до поточного користувача. Якщо це ключове слово відсутнє, код виконується в системному контексті.

Наприклад:

public with sharing class MyApexClass{
// sharing rules enforced when code in this class executes
}

Не ділячись

Якщо клас визначено за допомогою цього ключового слова, то правила спільного доступу, що застосовуються до поточного користувача, не застосовуються.

Наприклад:

public without sharing class MyApexClass{
// sharing rules are not enforced when code in this class executes
}

Статичний

Змінна або метод, визначені за допомогою ключового слова static, ініціалізуються один раз та асоціюються з класом. Статичні змінні та методи можна викликати безпосередньо за іменем класу, не створюючи екземпляр класу.

Остаточний

Константу або метод, визначені за допомогою ключового слова final, не можна перевизначити. Наприклад:

public class myCls {
static final Integer INT_CONST = 10;
}

Якщо ви спробуєте перевизначити значення цієї змінної INT_CONST, ви отримаєте виняток – System.FinalException: Final variable has already been initialized.

Повернення

Це ключове слово повертає значення з методу. Наприклад:

public String getName() {
return 'Test';
}

Null

Він визначає нульову константу та може бути присвоєний змінній. Наприклад:

Boolean b = null;

Віртуальний

Якщо клас визначено за допомогою ключового слова virtual, його можна розширити та перевизначити.

Abstract

Якщо клас визначено за допомогою abstracключове слово t, воно повинно містити принаймні один метод з ключовим словом abstract, і цей метод повинен мати лише підпис.

Наприклад:

public abstract class MyAbstractClass {
abstract Integer myAbstractMethod1();
}

Apex String

Рядок — це набір символів без обмеження кількості символів. Наприклад:

String name = 'Test';

Клас String у Salesforce пропонує кілька вбудованих методів. Нижче наведено кілька часто використовуваних методів:

скоротити (maxWidth)

Цей метод скорочує рядок до заданої довжини та повертає її, якщо довжина заданого рядка перевищує задану довжину; в іншому випадку він повертає початковий рядок. Якщо значення змінної maxWidth менше за 4, цей метод викидає виняток під час виконання – System.StringException: Мінімальна ширина абревіатури – 4.

Наприклад:

String s = 'Hello World';
String s2 = s.abbreviate(8);
System.debug('s2: ' + s2); //Hello...

використовувати великі літери ()

Цей метод перетворює першу літеру рядка на регістр заголовка та повертає її.

Наприклад:

String s = 'hello';
String s2 = s.capitalize();
System.assertEquals('Hello', s2);

містить (підрядок)

Цей метод повертає значення true, якщо рядок, що викликає метод, містить вказаний підрядок.

String name1 = 'test1';
String name2 = 'test';
Boolean flag = name1.contains(name2);
System.debug('flag:: ' + flag); //true

дорівнює (stringOrId)

Цей метод повертає значення true, якщо переданий параметр не є null та представляє ту саму двійкову послідовність символів, що й рядок, що викликає метод.

Під час порівняння значень ідентифікаторів довжини ідентифікаторів можуть не збігатися. Наприклад, якщо рядок, який представляє 15-символьний ідентифікатор, порівнюється з об'єктом, який представляє 18-символьний ідентифікатор, цей метод все одно повертає значення true. Наприклад:

String stringValue15 = '001D000000Ju1zH';
Id idValue18 = '001D000000Ju1zHIAR';
Boolean result = stringValue15.equals(idValue18);
System.debug('result: ' + result); //true

У наведеному вище прикладі метод equals порівнює 15-символьний ідентифікатор об'єкта з 18-символьним ідентифікатором об'єкта, і якщо обидва ідентифікатори представляють одну й ту саму двійкову послідовність, він повертає значення true.

Використовуйте цей метод для порівняння з урахуванням регістру.

escapeSingleQuotes(stringToEscape)

Цей метод додає escape-символ (\) перед будь-якими одинарними лапками в рядку та повертає результат. Цей метод запобігає SOQL-ін'єкції під час створення динамічного SOQL-запиту. Він гарантує, що всі одинарні лапки обробляються як рядки, що містять їх, а не як команди бази даних.

Наприклад:

String s = 'Hello \'Tom\'';
String escapedStr = String.escapeSingleQuotes(s);
System.debug(escapedStr); // Outputs Hello \'Tom\'

видалити (підрядок)

Цей метод видаляє всі екземпляри згаданого підрядка з рядка, який викликає метод, та повертає результуючий рядок.

Наприклад:

String s1 = 'Salesforce and force.com';
String s2 = s1.remove('force');
System.debug('s2: ' + s2); // 'Sales and .com'

підрядок (початковий індекс)

Цей метод повертає підрядок, який починається з символу в startIndex і продовжується до кінця рядка.

Наприклад:

String s1 = 'hamburger';
String s2 = s1.substring(3);
System.debug('s2: ' + s2); //burger

зворотний()

Цей метод інвертує всі символи рядка та повертає його. Наприклад:

String s = 'Hello';
String s2 = s.reverse();
System.debug('s2:::: ' + s2); // olleH

trim ()

Цей метод видаляє всі початкові та кінцеві пробіли з рядка та повертає його.

valueOf(toConvert)

Цей метод повертає рядкове представлення переданого об'єкта.

Рядки, класи та ключові слова об'єднуються, коли ви починаєте пакувати логіку в повторно використовувані одиниці, і саме для цього існують класи Apex.

Клас Апекс

Клас Apex — це креслення або шаблон, на основі якого створюються об'єкти. Об'єкт — це екземпляр класу.

Існує три способи створення класів Apex у Salesforce:

  • Консоль розробника
  • Visual Studio Code з пакетом розширення Salesforce
  • Сторінка деталей класу Apex у розділі налаштувань

В Apex можна визначити зовнішній клас, який також називають класом верхнього рівня, а також можна визначити класи всередині зовнішнього класу, які називаються внутрішніми класами.

Обов'язково використовувати модифікатор доступу, такий як global або public, в оголошенні зовнішнього класу.

Немає потреби використовувати модифікатор доступу в оголошенні внутрішніх класів.

Клас Apex визначається за допомогою ключового слова class, за яким слідує ім'я класу.

Ключове слово extends використовується для розширення існуючого класу в класі Apex, а ключове слово implements використовується для реалізації інтерфейсу в класі Apex.

Salesforce Apex не підтримує множинне успадкування; клас Apex може розширювати лише один існуючий клас Apex, але може реалізовувати кілька інтерфейсів.

Клас Apex може містити користувацький конструктор, а якщо користувацький конструктор недоступний, використовується конструктор за замовчуванням. Код у конструкторі виконується під час створення екземпляра класу.

Синтаксис класу Apex:

public class myApexClass{
// variable declaration
//constructor
	public myApexClass(){
	}
//methods declaration
}

Ключове слово new використовується для створення екземпляра класу Apex. Нижче наведено синтаксис для створення екземпляра класу Apex:

myApexClass obj = new myApexClass();

Apex Getter і Setter

Властивість Apex подібна до змінної Apex. Для властивості Apex необхідні геттер та сеттер. Їх можна використовувати для виконання коду перед тим, як значення властивості буде доступне або змінено. Код в аксессорі get виконується, коли значення властивості зчитується. Код в аксессорі set виконується, коли значення властивості змінюється. Будь-яка властивість, що має лише аксессор get, вважається доступною лише для читання, будь-яка властивість, що має лише аксессор set, вважається доступною лише для запису, а будь-яка властивість, що має обидва аксессори get та set, вважається доступною для читання та запису. Синтаксис властивості Apex:

public class myApexClass {
// Property declaration
	access_modifier return_type property_name {
	get {
			//code
		}
		set{
			//code
		}
	}
}

Тут access_modifier – це модифікатор доступу властивості, return_type – це тип даних властивості, а property_name – це назва властивості.

Нижче наведено приклад властивості Apex, яка має як аксессори get, так і set:

public class myApex{
	public String name{
		get{ return name; }
		set{ name = value; }
	}
}

Тут назва властивості — name, вона є публічною властивістю та повертає тип даних String.

Необов'язково мати код у блоках get та set. Ці блоки можна залишити порожніми для визначення автоматичної властивості. Наприклад:

public double MyReadWriteProp{ get; set; }

Методи доступу Get та Set також можуть бути визначені з власними модифікаторами доступу. Якщо метод доступу визначено з модифікатором, він перевизначає модифікатор доступу властивості. Наприклад:

public String name{private get; set;}// name is private for read and public for write.

Класи визначають логіку повторного використання, яку ви викликаєте явно. Тригери, які розглядаються далі, запускаються автоматично щоразу, коли записи змінюються.

Тригер Apex

Тригери Apex дозволяють виконувати користувацькі Apex до та після виконання операції DML.

Apex підтримує такі два типи тригерів:

Перед тригерами: Ці тригери використовуються для перевірки та оновлення значення поля перед збереженням запису в базі даних.

Після тригерів: Ці тригери використовуються для доступу до значень полів (таких як ідентифікатор запису та поле LastModifiedDate), які встановлюються системою після того, як запис буде додано до бази даних. Ці значення полів можна використовувати для зміни інших записів. Записи, що спрацьовують після тригерів, доступні лише для читання.

Найкращою практикою є написання групових тригерів. Груповий тригер може обробляти як один запис, так і кілька записів одночасно.

Синтаксис тригера Apex:

trigger TriggerName on ObjectName (trigger_events) {
	//Code_block
 }

Тут TriggerName – це назва тригера, ObjectName – це назва об’єкта, для якого записано тригер, а trigger_events – це список подій, розділених комами.

Нижче наведено події, що підтримуються тригерами Apex: перед вставкою, перед оновленням, перед видаленням, після вставки, після оновлення, після видалення, після відновлення видалення.

Статичні ключові слова не можна використовувати в тригері Apex. Усі ключові слова, що застосовуються до внутрішніх класів, можна використовувати в тригері Apex.

Кожен тригер визначає неявні змінні, які повертають контекст виконання. Ці змінні визначені в класі System.Trigger і називаються контекстними змінними. На двох знімках екрана нижче перелічено контекстні змінні, що підтримуються тригерами Apex:

Змінні контексту тригера Apex

Контекстні змінні тригера Apex (продовження)

Нижче наведено міркування щодо контекстних змінних у тригерах Apex:

  • Не використовуйте trigger.new та trigger.old в операціях DML.
  • Trigger.new неможливо видалити.
  • Trigger.new доступний лише для читання в after-тригерах.
  • Trigger.new можна використовувати для зміни значень полів того самого об'єкта лише у попередніх тригерах.

На двох знімках екрана нижче наведено міркування щодо конкретних дій у різних тригерних подіях:

Міркування щодо подій Apex Trigger

Міркування щодо подій апексного тригера (продовження)

Тригери обробляють логіку реального часу, але деякі завдання просто занадто великі для однієї транзакції. Саме тут і приходить на допомогу пакетний Apex.

Пакетний клас в Apex

Пакетний клас у Salesforce використовується для обробки великої кількості записів, які перевищили б ліміти регулятора Apex за умови звичайної обробки. Пакетний клас виконує код асинхронно.

Нижче наведено переваги пакетного класу:

  • Пакетний клас обробляє дані фрагментами, і якщо один фрагмент не вдається обробити успішно, успішно оброблені фрагменти не відкочуються.
  • Кожен фрагмент даних у пакетному класі обробляється з новим набором обмежень регулятора, що гарантує, що код виконується в межах обмежень виконання регулятора.

Інтерфейс Database.Batchable має бути реалізований класом Apex для використання як пакетний клас. Він надає три методи, які мають бути реалізовані класом batch:

1. початок()

Цей метод генерує область видимості записів або об'єктів, які будуть оброблені методом інтерфейсу execute. Він викликається лише один раз під час виконання пакетної операції. Цей метод повертає або об'єкт Database.QueryLocator, або об'єкт Iterable. Кількість записів, які можна отримати за допомогою запиту SOQL з використанням об'єкта Database.QueryLocator, становить 50 мільйонів, але при використанні об'єкта Iterable загальна кількість записів, які можна отримати за допомогою запиту SOQL, становить лише 50 000. Iterable використовується для створення складної області видимості для класу batch.

Синтаксис методу start:

global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {}

2. виконати()

Цей метод використовується для обробки кожного фрагмента даних. Метод execute викликається для кожного фрагмента записів. Розмір пакета виконання за замовчуванням становить 200 записів. Метод execute приймає два аргументи:

Посилання на об’єкт Database.BatchableContext,

Список sObjects, наприклад List , або список параметризованих типів. Синтаксис методу execute:

global void execute(Database.BatchableContext bc, List<P> records){}

3. завершення()

Метод finish викликається один раз під час виконання класу пакетної обробки. У методі finish можна виконувати операції постобробки. Наприклад: надсилання електронного листа з підтвердженням. Цей метод викликається, коли всі пакети обробки завершено. Синтаксис методу finish:

global void finish(Database.BatchableContext bc){}

Об'єкт Database.BatchableContext

Кожен метод інтерфейсу Database.Batchable має посилання на об'єкт Database.BatchableContext.

Цей об'єкт використовується для track прогрес пакетного завдання.

Нижче наведено методи екземпляра, що надаються BatchableContext:

  • getChildJobId(): Цей метод повертає ідентифікатор пакетного завдання, яке наразі обробляється.
  • getJobId(): цей метод повертає ідентифікатор пакетного завдання.

Нижче наведено синтаксис пакетного класу:

global class MyBatchClass implements Database.Batchable<sObject> {
	global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {
// collect the batches of records or objects to be passed to execute
}
global void execute(Database.BatchableContext bc, List<P> records){
// process each batch of records
}
global void finish(Database.BatchableContext bc){
// execute any post-processing operations
}
}

Метод Database.executeBatch

Метод Database.executeBatch використовується для виконання пакетного класу.

Цей метод приймає два параметри: екземпляр класу пакета, який потрібно обробити, та необов'язковий параметр області видимості для визначення розміру пакета. Якщо його не вказано, використовується розмір за замовчуванням, що дорівнює 200.

Синтаксис Database.executeBatch:

Database.executeBatch(myBatchObject, scope)

Виконання пакетного класу з назвою MyBatchClass:

MyBatchClass myBatchObject = new MyBatchClass();
Id batchId = Database.executeBatch(myBatchObject, 100);

База даних.Stateful

Клас пакетної обробки за замовчуванням не зберігає стан. Щоразу, коли викликається метод execute, отримується нова копія об'єкта, а всі змінні класу ініціалізуються.

Database.Stateful реалізовано для того, щоб пакетний клас мав стан.

Якщо ваш пакетний клас реалізує Database.Інтерфейс зі збереженням стану, всі змінні екземпляра зберігають свої значення, але статичні змінні скидаються між транзакціями.

Асинхронний пакет Apex Beyond

Batch Apex — це лише один із кількох способів асинхронного виконання коду. Salesforce пропонує чотири асинхронні варіанти, і вибір правильного залежить від обсягу даних, які ви обробляєте, та від того, чи потрібно завдання об’єднувати в ланцюжок, чи планувати.

  • Майбутні методи: Анотовані як @future, вони найкраще підходять для простих операцій типу «запустив і забув», таких як виклики зовнішніх веб-сервісів.
  • Apex, що можна поставити в чергу: Реалізує інтерфейс Queueable, приймає складні типи об'єктів, повертає ідентифікатор завдання та підтримує ланцюжок одного завдання з іншим.
  • Пакетний апекс: Обробляє дуже великі обсяги даних фрагментами, як описано вище.
  • Запланований Апекс: Реалізує інтерфейс Schedulable, щоб клас запускався у певний час, наприклад, щонічне завдання очищення.
тип Best For Ключові можливості
Майбутній метод Прості виклики Вогонь і забуй
Apex, що можна поставити в чергу Послідовна обробка Ланцюжок завдань та моніторинг
Пакетний Apex Мільйони записів Подрібнена обробка
Запланований Апекс Повторювані вакансії Таймінг на основі Cron

Яку б модель виконання ви не обрали, кожна транзакція все одно вимірюється відповідно до лімітів регулятора для всієї платформи, перелічених нижче.

Межі регулятора Apex

Ліміти регуляторів Apex – це ліміти, що застосовуються механізмом виконання Apex, щоб гарантувати, що будь-який неконтрольований код та процеси Apex не монополізуватимуть спільні ресурси та не порушуватимуть обробку інших користувачів у багатокористувацькому середовищі. Ці ліміти перевіряються для кожної транзакції Apex. Нижче наведено ліміти регуляторів, визначені Salesforce для кожної транзакції Apex:

Опис Limit
Запити SOQL, які можна виконати в синхронній транзакції 100
SOQL-запити, які можна виконувати в асинхронній транзакції 200
Записи, які можна отримати за допомогою запиту SOQL 50,000
Записи, які можна отримати за допомогою Database.getQueryLocator 10,000
SOSL-запити, які можна виконати в транзакції Apex 20
Записи, які можна отримати за допомогою запиту SOSL 2,000
Оператори DML, які можна виконувати в транзакції Apex 150
Записи, які можна обробити в результаті оператора DML, Approval.process або database.emptyRecycleBin 10,000
Виклики, які можна виконати в транзакції Apex 100
Сукупний ліміт часу очікування для всіх викликів, що виконуються в транзакції Apex 120 секунд:
Обмеження на кількість завдань Apex, які можна додати до черги за допомогою System.enqueueJob 50
Обмеження часу виконання для кожної транзакції Apex 10 хвилин
Обмеження на символи, які можна використовувати в класі та тригері Apex 1 млн
Обмеження часу процесора для синхронної транзакції 10,000 мілісекунд
Обмеження часу процесора для асинхронної транзакції 60,000 мілісекунд
Загальний розмір купи 6 МБ (синхронно) / 12 МБ (асинхронно)

Як написати тестовий клас в Apex

Salesforce вимагає, щоб щонайменше 75 відсотків вашого коду Apex було охоплено модульними тестами, перш ніж ви зможете розгорнути його у продакшені, і кожен тригер повинен мати певне покриття. Тому написання тестових класів є основною навичкою Apex, а не додатковим доповненням.

Тестовий клас позначається тегом @isTest, а кожен тестовий метод також позначається тегом @isTest. Тестові методи не передадуть дані до бази даних і не бачать більшість існуючих даних організації, тому кожен тест створює власні записи. Методи Test.startTest() та Test.stopTest() надають тестованому коду новий набір обмежень регулятора, а твердження перевіряють, чи логіка поводилася належним чином.

Ось простий тестовий клас для логіки створення облікового запису:

@isTest
private class AccountHandlerTest {
    @isTest
    static void testCreateAccount() {
        Account acc = new Account(Name = 'Test Account');
        Test.startTest();
        insert acc;
        Test.stopTest();
        Account result = [SELECT Id, Name FROM Account WHERE Id = :acc.Id];
        System.assertEquals('Test Account', result.Name);
    }
}

Дотримуйтесь цих правил під час написання тестів:

  • Використовуйте метод @testSetup для створення спільних тестових даних один раз для всіх тестових методів у класі.
  • Перевірте масову поведінку, вставивши 200 записів, а не лише один.
  • Охопіть позитивні, негативні сценарії та сценарії з обмеженим доступом до користувачів.
  • Завжди включайте змістовні оператори System.assert; покриття без тверджень нічого не доводить.

Найкращі практики Apex

Початківці часто пишуть Apex, який працює для одного запису, але не працює в реальних масових операціях. Наведені нижче методи дозволяють утримувати ваш код у межах обмежень регулятора та полегшують його підтримку:

  • Збільшити обсяг усього: Напишіть логіку, яка обробляє колекції записів, оскільки тригери можуть отримувати до 200 записів за один пакет.
  • Уникайте циклів у SOQL та DML: Зробіть запит перед циклом, зберіть зміни у списку та виконайте один DML-інструкцію після циклу.
  • Один тригер на об'єкт: Зберігайте тригери без логіки та делегуйте роботу класам обробників, що робить порядок виконання передбачуваним.
  • Використовувати з обміном: Забезпечте безпеку на рівні записів, якщо немає задокументованої причини для запуску в системному контексті.
  • Уникайте жорсткого кодування ідентифікаторів: Ідентифікатори записів відрізняються між ізольованими середовищами та робочими середовищами, тому запитуйте їх або використовуйте натомість користувацькі метадані.
  • Моніторинг обмежень у коді: Методи класу Limits, такі як Limits.getQueries(), дозволяють перевіряти споживання ресурсів під час виконання.

💡 Порада: Перед розгортанням запустіть свій код на 200 записах у пісочниці. Більшість збоїв обмеження регуляторів виникають лише при масовому використанні, і їх раннє виявлення набагато дешевше, ніж налагодження у продакшені.

Поширені запитання

Ні. Apex позичає Javaсинтаксис, подібний до -, але він не враховує регістр, працює лише на платформі Salesforce Lightning, інтегрує SOQL безпосередньо в мову та регулюється обмеженнями на кількість транзакцій, які Java не має.

Зареєструйтесь у безкоштовній організації Salesforce Developer Edition, яка включає Консоль розробника, та виконайте практичні вправи Трейлхед, офіційна навчальна платформа від Salesforce.

Visualforce — це мова розмітки для створення сторінок інтерфейсу користувача, тоді як Apex — це серверна мова, яка забезпечує логіку, що лежить в їх основі. Сторінки Visualforce часто викликають класи контролерів Apex для запитів та оновлення даних.

Так. Agentforce для розробників, помічник зі штучного інтелекту від Salesforce для Visual Studio Code, генерує та пояснює Apex на основі підказок природною мовою. Завжди перевіряйте та тестуйте код, згенерований штучним інтелектом, на відповідність обмеженням регулятора перед розгортанням.

Класи Apex, позначені анотацією @InvocableMethod, можуть бути представлені як користувацькі дії, що дозволяє ботам Einstein та агентам Agentforce викликати вашу бізнес-логіку, тоді як Apex також може викликати шаблони запитів Einstein та моделі штучного інтелекту через API платформи.

Підсумуйте цей пост за допомогою: