Tutorial de Salesforce Apex para iniciantes

⚡ Resumo Inteligente

A programação Apex oferece aos desenvolvedores Salesforce uma linguagem orientada a objetos e fortemente tipada para adicionar lógica de negócios personalizada ao CRM. Ela viabiliza classes, gatilhos e trabalhos em lote, enquanto os limites de governança mantêm a plataforma multilocatária compartilhada estável.

  • 🧱 Foundation: Apex é uma linguagem que não diferencia maiúsculas de minúsculas. JavaSintaxe semelhante à do Salesforce Lightning, que funciona nativamente na plataforma Salesforce Lightning.
  • 🗃️ Acesso de dados: As consultas SOQL e as instruções DML permitem que seu código leia e grave registros sObject diretamente no banco de dados do Salesforce.
  • 🛠️ Implementação: Classes, propriedades e gatilhos associam lógica personalizada a inserções, atualizações, exclusões de registros e outros eventos do sistema.
  • 📦 Escala: O Batch Apex e outras opções assíncronas processam milhões de registros em lotes sem ultrapassar os limites da plataforma.
  • 🚦 Limites do governador: Limites por transação, como 100 consultas SOQL síncronas e 150 instruções DML, protegem os recursos compartilhados.
  • ✅ Qualidade: Os testes unitários devem cobrir pelo menos 75% do código Apex antes da implantação em produção.

Visão geral da programação APEX Salesforce

O que é Apex no Salesforce?

ápice Apex é uma linguagem de programação orientada a objetos e fortemente tipada, desenvolvida pela Salesforce para a criação de aplicativos de Software como Serviço (SaaS) e de Gestão de Relacionamento com o Cliente (CRM). O Apex auxilia desenvolvedores na criação de aplicativos SaaS de terceiros e na adição de lógica de negócios a eventos do sistema, fornecendo suporte a bancos de dados e interfaces cliente-servidor.

O Apex ajuda os desenvolvedores a adicionar lógica de negócios a eventos do sistema, como cliques em botões, atualizações de registros relacionados e páginas do Visualforce. O Apex tem uma sintaxe semelhante a... Java. Registre-se no Salesforce Para aprender como funciona o CRM.

Recursos da linguagem de programação Apex

Aqui estão os recursos importantes do Salesforce Apex:

  • Apex é uma linguagem que não diferencia maiúsculas de minúsculas.
  • Você pode executar operações DML como INSERT, UPDATE, UPSERT e DELETE em registros sObject usando Apex.
  • Você pode consultar registros de sObject usando SOQL (Salesforce Object Query Language) e SOSL (Salesforce Object Search Language) no Apex.
  • Permite que você crie um teste de unidade e executá-lo para verificar o Cobertura de código e a eficiência do código em Apex.
  • O Apex é executado em um ambiente multilocatário e Salesforce O Salesforce definiu limites de governança que impedem um usuário de monopolizar os recursos compartilhados. Qualquer código que ultrapasse um limite de governança do Salesforce falhará e um erro será exibido.
  • Um objeto do Salesforce pode ser usado como um tipo de dados no Apex. Por exemplo:
    Account acc = new Account();

    Aqui, "Conta" é um objeto padrão do Salesforce.

  • O Apex é atualizado automaticamente a cada versão do Salesforce.

Quando um desenvolvedor deve escolher o Apex?

O código Apex só deve ser escrito se um cenário de negócios for complexo demais para ser implementado usando a funcionalidade pré-construída de apontar e clicar fornecida pelo Salesforce.

A seguir, apresentamos alguns cenários em que você precisará escrever código Apex:

  • Para criar serviços web que integram o Salesforce com outros aplicativos.
  • Para implementar validação personalizada em sObjects.
  • Para executar lógica Apex personalizada quando uma operação DML for realizada.
  • Para implementar funcionalidades que não podem ser criadas com as ferramentas de automação declarativa existentes, como o Flow.
  • Para configurar serviços de email que processam o conteúdo, os cabeçalhos e os anexos dos e-mails recebidos.

Depois de saber quando o Apex é a escolha certa, o próximo passo é entender o que acontece com o seu código depois de salvá-lo.

Estrutura de funcionamento do Apex

A seguir, o fluxo de ações para o código Apex:

  • Ação do desenvolvedor: Quando o desenvolvedor salva o código na plataforma, todo o código Apex é compilado em um conjunto de instruções que o interpretador de tempo de execução do Apex consegue entender, e essas instruções são então salvas como metadados na plataforma.
  • Ação do usuário final: Quando um evento de usuário executa código Apex, o servidor da plataforma recupera as instruções compiladas dos metadados e as executa por meio do interpretador Apex antes de retornar o resultado.

O diagrama abaixo mostra como as ações do desenvolvedor e do usuário final interagem com o servidor de aplicativos da Lightning Platform:

Estrutura de trabalho do Apex

Ambiente de desenvolvimento Apex

O código Apex pode ser desenvolvido tanto em um ambiente de teste (sandbox) quanto em uma organização Developer Edition do Salesforce.

É uma boa prática desenvolver o código em um ambiente de teste (sandbox) e, em seguida, implantá-lo no ambiente de produção, conforme ilustrado abaixo:

Ambiente de desenvolvimento Apex

Ferramentas de desenvolvimento de código Apex: A seguir, apresentamos as três ferramentas disponíveis para desenvolver código Apex em todas as edições do Salesforce:

  • Console do desenvolvedor
  • Visual Studio Code com o Salesforce Extension Pack (que substitui o Force.com IDE descontinuado)
  • Code editor na interface do usuário de configuração do Salesforce

Com o ambiente pronto, vamos analisar os elementos básicos da linguagem em si, começando pelos tipos de dados.

Tipos de dados no Apex

A seguir, estão os tipos de dados suportados pelo Apex:

Primitivo

Inteiro, DoubleOs tipos de dados primitivos são: `long`, `date`, `datetime`, `decimal`, `time`, `blob`, `string`, `ID` e `boole`. Todos os tipos de dados primitivos são passados ​​por valor, não por referência.

Coleções

Existem três tipos de coleções disponíveis no Apex:

  • Lista: É uma coleção ordenada de elementos primitivos, sObjects, coleções ou objetos Apex, baseada em índices.
  • Conjunto: Uma coleção não ordenada de elementos únicos que não contém duplicados.
  • Mapa: É uma coleção de chaves únicas que correspondem a valores individuais, que podem ser tipos primitivos, sObjects, coleções ou objetos Apex.

objeto

Este é um tipo de dados especial no Salesforce. É semelhante a uma tabela em SQL e contém campos semelhantes a colunas em SQL.

Enums

Um Enum é um absolutotracTipo de dados t que armazena um valor de um conjunto finito de identificadores especificados.

Classes, objetos e interfaces

Classes e interfaces Apex definidas pelo usuário também podem ser usadas como tipos de dados. Um objeto se refere a uma instância de qualquer tipo de dado compatível com o Apex.

Sintaxe do ápice

Declaração de Variável

Como o Apex é uma linguagem fortemente tipada, é obrigatório declarar uma variável com um tipo de dados no Apex.

Por exemplo:

Contact con = new Contact();

Aqui, a variável `con` é declarada com `Contact` como seu tipo de dados.

Consulta SOQL

SOQL significa Salesforce Object Query Language (Linguagem de Consulta de Objetos do Salesforce). O SOQL é usado para buscar registros de sObjects no banco de dados do Salesforce. Por exemplo:

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

A consulta acima recupera um registro de conta do banco de dados do Salesforce.

Declaração de loop

Uma estrutura de laço é usada para iterar sobre os registros em uma lista. O número de iterações é igual ao número de registros na lista. Por exemplo:

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

No trecho de código acima, listOfAccounts é uma variável do tipo de dados List.

Declaração de controle de fluxo

Uma instrução de controle de fluxo é útil quando você deseja executar algumas linhas de código com base em determinadas condições.

Por exemplo:

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
}

O trecho de código acima consulta os registros de contas no banco de dados e verifica o tamanho da lista.

Declaração DML

DML significa Linguagem de Manipulação de Dados. As instruções DML são usadas para manipular dados no banco de dados do Salesforce. Por exemplo:

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

Especificadores de acesso Apex

A seguir estão os especificadores de acesso suportados pelo Apex:

Público

Este especificador de acesso concede acesso a uma classe, método ou variável para ser usada pelo Apex dentro de um namespace.

Privado

Este especificador de acesso permite o uso local de uma classe, método ou variável, ou seja, dentro da seção de código onde ela está definida. Todos os métodos e variáveis ​​que não possuem um especificador de acesso definido assumem o especificador de acesso padrão `private`.

Protegido

Este especificador de acesso concede acesso a um método ou variável que poderá ser usado por quaisquer classes internas dentro da classe Apex que o define.

Cobertura

Este especificador de acesso permite que o Apex acesse uma classe, método ou variável tanto dentro quanto fora de um namespace. É uma boa prática não usar a palavra-chave `global` a menos que seja necessário.

Palavras-chave no Apex

Com compartilhamento

Se uma classe for definida com esta palavra-chave, todas as regras de compartilhamento aplicáveis ​​ao usuário atual serão aplicadas. Se esta palavra-chave estiver ausente, o código será executado no contexto do sistema.

Por exemplo:

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

Sem compartilhar

Se uma classe for definida com esta palavra-chave, as regras de compartilhamento aplicáveis ​​ao usuário atual não serão aplicadas.

Por exemplo:

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

Estático

Uma variável ou método definido com a palavra-chave `static` é inicializado uma única vez e associado à classe. Variáveis ​​e métodos estáticos podem ser chamados diretamente pelo nome da classe, sem a necessidade de criar uma instância da classe.

final

Uma constante ou método definido com a palavra-chave final não pode ser sobrescrito. Por exemplo:

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

Se você tentar sobrescrever o valor dessa variável INT_CONST, receberá a exceção – System.FinalException: A variável final já foi inicializada.

Devolução

Esta palavra-chave retorna um valor de um método. Por exemplo:

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

Nulo

Define uma constante nula e pode ser atribuída a uma variável. Por exemplo:

Boolean b = null;

Virtual

Se uma classe for definida com a palavra-chave virtual, ela poderá ser estendida e sobrescrita.

Sumário

Se uma classe for definida com o valor absolutotracA palavra-chave `t` deve conter pelo menos um método com a palavra-chave `abs`.tract, e esse método deve ter apenas uma assinatura.

Por exemplo:

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

Seqüência de Ápice

Uma string é um conjunto de caracteres sem limite de caracteres. Por exemplo:

String name = 'Test';

Existem vários métodos integrados fornecidos pela classe String no Salesforce. A seguir, alguns dos métodos mais utilizados:

abreviar (largura máxima)

Este método trunca uma string para o comprimento especificado e a retorna se o comprimento da string fornecida for maior que o comprimento especificado; caso contrário, retorna a string original. Se o valor da variável `maxWidth` for menor que 4, este método lançará uma exceção em tempo de execução: `System.StringException: Minimum abbreviation width is 4`.

Por exemplo:

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

capitalizar()

Este método converte a primeira letra de uma string em maiúsculas e minúsculas e a retorna.

Por exemplo:

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

contém (substring)

Este método retorna verdadeiro se a string que o chama contiver a substring especificada.

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

é igual(stringOrId)

Este método retorna verdadeiro se o parâmetro passado não for nulo e representar a mesma sequência binária de caracteres que a string que está chamando o método.

Ao comparar valores de ID, os comprimentos dos IDs podem não ser iguais. Por exemplo, se uma string que representa um ID de 15 caracteres for comparada com um objeto que representa um ID de 18 caracteres, este método ainda retornará verdadeiro. Por exemplo:

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

No exemplo acima, o método equals compara um ID de objeto de 15 caracteres com um ID de objeto de 18 caracteres e, se ambos os IDs representarem a mesma sequência binária, retorna verdadeiro.

Use este método para fazer comparações que diferenciam maiúsculas de minúsculas.

escapeSingleQuotes(stringToEscape)

Este método adiciona um caractere de escape (\) antes de qualquer aspa simples em uma string e retorna o resultado. Ele impede a injeção de SOQL durante a criação de uma consulta SOQL dinâmica, garantindo que todas as aspas simples sejam tratadas como strings delimitadoras em vez de comandos de banco de dados.

Por exemplo:

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

remover(substring)

Este método remove todas as ocorrências da substring mencionada da string que chama o método e retorna a string resultante.

Por exemplo:

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

substring(startIndex)

Este método retorna uma substring que começa no caractere em startIndex e se estende até o final da string.

Por exemplo:

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

marcha ré()

Este método inverte todos os caracteres de uma string e a retorna. Por exemplo:

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

aparar()

Este método remove todos os espaços em branco iniciais e finais de uma string e a retorna.

valorOf(paraConverter)

Este método retorna a representação em formato de string do objeto passado como parâmetro.

Strings, classes e palavras-chave se unem quando você começa a empacotar a lógica em unidades reutilizáveis, que é exatamente para isso que servem as classes Apex.

Classe Apex

Uma classe Apex é um modelo ou projeto a partir do qual os objetos são criados. Um objeto é uma instância de uma classe.

Existem três maneiras de criar classes Apex no Salesforce:

  • Console do desenvolvedor
  • Visual Studio Code com o pacote de extensões do Salesforce
  • Página de detalhes da classe Apex em Configuração

Em Apex, você pode definir uma classe externa, também chamada de classe de nível superior, e também pode definir classes dentro de uma classe externa, chamadas de classes internas.

É obrigatório usar um modificador de acesso como global ou público na declaração de uma classe externa.

Não é necessário usar um modificador de acesso na declaração de classes internas.

Uma classe Apex é definida usando a palavra-chave `class` seguida pelo nome da classe.

A palavra-chave `extends` é usada para estender uma classe existente em uma classe Apex, e a palavra-chave `implements` é usada para implementar uma interface em uma classe Apex.

O Salesforce Apex não suporta herança múltipla; uma classe Apex só pode estender uma classe Apex existente, mas pode implementar várias interfaces.

Uma classe Apex pode conter um construtor definido pelo usuário e, caso um construtor definido pelo usuário não esteja disponível, um construtor padrão será utilizado. O código dentro de um construtor é executado quando uma instância da classe é criada.

Sintaxe de uma classe Apex:

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

A palavra-chave `new` é usada para criar uma instância de uma classe Apex. Abaixo está a sintaxe para criar uma instância de uma classe Apex:

myApexClass obj = new myApexClass();

Apex Getter e Setter

Uma propriedade Apex é semelhante a uma variável Apex. Um getter e um setter são necessários para uma propriedade Apex. Eles podem ser usados ​​para executar código antes que o valor da propriedade seja acessado ou alterado. O código no acessador get é executado quando o valor de uma propriedade é lido. O código no acessador set é executado quando o valor de uma propriedade é alterado. Qualquer propriedade que tenha apenas um acessador get é considerada somente leitura, qualquer propriedade que tenha apenas um acessador set é considerada somente gravação e qualquer propriedade que tenha acessadores get e set é considerada leitura e gravação. Sintaxe de uma propriedade Apex:

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

Aqui, `access_modifier` é o modificador de acesso da propriedade, `return_type` é o tipo de dados da propriedade e `property_name` é o nome da propriedade.

Abaixo, segue um exemplo de uma propriedade Apex que possui acessadores get e set:

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

Neste caso, o nome da propriedade é "name", trata-se de uma propriedade pública e retorna um tipo de dados String.

Não é obrigatório ter código nos blocos get e set. Esses blocos podem ser deixados vazios para definir uma propriedade automática. Por exemplo:

public double MyReadWriteProp{ get; set; }

Os acessadores get e set também podem ser definidos com seus próprios modificadores de acesso. Se um acessador for definido com um modificador, ele substituirá o modificador de acesso da propriedade. Por exemplo:

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

As classes definem uma lógica reutilizável que você chama explicitamente. Os gatilhos, abordados a seguir, são executados automaticamente sempre que os registros são alterados.

Acionador do Apex

Os gatilhos Apex permitem executar código Apex personalizado antes e depois da execução de uma operação DML.

O Apex suporta os dois tipos de gatilhos a seguir:

Antes dos gatilhos: Esses gatilhos são usados ​​para validar e atualizar o valor de um campo antes que o registro seja salvo no banco de dados.

Após os gatilhos: Esses gatilhos são usados ​​para acessar valores de campos (como o ID do registro e o campo LastModifiedDate) que são definidos pelo sistema após um registro ser gravado no banco de dados. Esses valores de campo podem ser usados ​​para modificar outros registros. Os registros acionados por gatilhos são somente leitura.

É uma boa prática escrever gatilhos otimizados para processamento em lote. Um gatilho otimizado para processamento em lote pode processar um único registro, bem como vários registros simultaneamente.

Sintaxe de um gatilho Apex:

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

Aqui, TriggerName é o nome do gatilho, ObjectName é o nome do objeto no qual o gatilho está escrito e trigger_events é uma lista de eventos separados por vírgulas.

Os seguintes eventos são suportados pelos gatilhos Apex: antes da inserção, antes da atualização, antes da exclusão, após a inserção, após a atualização, após a exclusão e após a recuperação da exclusão.

Palavras-chave estáticas não podem ser usadas em um gatilho Apex. Todas as palavras-chave aplicáveis ​​a classes internas podem ser usadas em um gatilho Apex.

Existem variáveis ​​implícitas definidas por cada gatilho que retornam o contexto de tempo de execução. Essas variáveis ​​são definidas na classe System.Trigger e são chamadas de variáveis ​​de contexto. As duas capturas de tela abaixo listam as variáveis ​​de contexto suportadas pelos gatilhos Apex:

Variáveis ​​de contexto do gatilho Apex

Variáveis ​​de contexto do gatilho Apex (continuação)

A seguir, apresentamos as considerações para variáveis ​​de contexto em gatilhos Apex:

  • Não utilize trigger.new e trigger.old em operações DML.
  • O arquivo Trigger.new não pode ser excluído.
  • Trigger.new é somente leitura em gatilhos posteriores.
  • O método `trigger.new` pode ser usado para alterar os valores de campos no mesmo objeto somente em gatilhos `before`.

As duas capturas de tela abaixo listam as considerações sobre ações específicas em diferentes eventos de gatilho:

Considerações sobre o evento de disparo Apex

Considerações sobre o evento de disparo Apex (continuação)

Os gatilhos lidam com a lógica em tempo real, mas algumas tarefas são simplesmente grandes demais para uma única transação. É aí que entra o Apex em lote.

Classe de lote no Apex

Uma classe em lote no Salesforce é usada para processar um grande número de registros que excederiam os limites do Apex se processados ​​normalmente. Uma classe em lote executa o código de forma assíncrona.

A seguir, as vantagens de uma aula em lote:

  • Uma classe de processamento em lote processa os dados em partes, e se uma parte não for processada com sucesso, as partes processadas com sucesso não são revertidas.
  • Cada bloco de dados em uma classe batch é processado com um novo conjunto de limites de governança, o que garante que o código seja executado dentro dos limites de execução definidos.

A interface Database.Batchable deve ser implementada por uma classe Apex para ser usada como uma classe de lote. Ela fornece três métodos que devem ser implementados pela classe de lote:

1. iniciar()

Este método gera o escopo de registros ou objetos a serem processados ​​pelo método de interface `execute`. Ele é chamado apenas uma vez durante a execução do lote. Este método retorna um objeto `Database.QueryLocator` ou um `Iterable`. O número de registros que podem ser recuperados por uma consulta SOQL usando o objeto `Database.QueryLocator` é de 50 milhões, mas usando um `Iterable`, o número total de registros que podem ser recuperados pela consulta SOQL é de apenas 50,000. Um `Iterable` é usado para gerar um escopo complexo para a classe de lote.

Sintaxe do método start:

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

2. executar()

Este método é usado para processar cada bloco de dados. O método `execute` é chamado para cada bloco de registros. O tamanho padrão do lote para execução é de 200 registros. O método `execute` recebe dois argumentos:

Uma referência ao objeto Database.BatchableContext,

Uma lista de sObjects, como List ou uma lista de tipos parametrizados. Sintaxe do método execute:

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

3. finalizar()

O método `finish` é chamado uma vez durante a execução da classe em lote. Operações de pós-processamento podem ser realizadas no método `finish`. Por exemplo: enviar um e-mail de confirmação. Este método é chamado quando todos os lotes são processados. Sintaxe do método `finish`:

global void finish(Database.BatchableContext bc){}

Objeto Database.BatchableContext

Cada método da interface Database.Batchable possui uma referência a um objeto Database.BatchableContext.

Este objeto é usado para track o progresso do trabalho em lote.

A seguir estão os métodos de instância fornecidos por BatchableContext:

  • getChildJobId(): Este método retorna o ID do trabalho em lote que está sendo processado no momento.
  • getJobId(): este método retorna o ID do trabalho em lote.

A seguir está a sintaxe de uma classe em lote:

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
}
}

Método Database.executeBatch

O método Database.executeBatch é usado para executar uma classe em lote.

Este método recebe dois parâmetros: uma instância da classe de lote a ser processada e um parâmetro de escopo opcional para especificar o tamanho do lote. Se não for especificado, o tamanho padrão de 200 será utilizado.

Sintaxe de Database.executeBatch:

Database.executeBatch(myBatchObject, scope)

Executando uma classe em lote chamada MyBatchClass:

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

Banco de dados com estado

Por padrão, uma classe em lote não mantém estado. Cada vez que o método execute é chamado, uma nova cópia do objeto é recebida e todas as variáveis ​​da classe são inicializadas.

O método `Database.Stateful` é implementado para tornar uma classe de lote com estado.

Se sua classe de lote implementar o banco de dadosNa interface .Stateful, todas as variáveis ​​de instância mantêm seus valores, mas as variáveis ​​estáticas são redefinidas entre as transações.

Apex assíncrono além do Batch

O Batch Apex é apenas uma das várias maneiras de executar código de forma assíncrona. O Salesforce oferece quatro opções assíncronas, e a escolha da mais adequada depende da quantidade de dados que você processa e se os trabalhos precisam ser encadeados ou agendados.

  • Métodos futuros: Anotadas com @future, essas são as melhores para operações simples e rápidas, como chamadas para serviços web externos.
  • Apex enfileirado: Implementa a interface Queueable, aceita tipos de objetos complexos, retorna um ID de tarefa e suporta o encadeamento de uma tarefa a outra.
  • Apex em lote: Processa volumes de dados muito grandes em partes, conforme descrito acima.
  • Ápice programado: Implementa a interface Schedulable para que uma classe seja executada em um horário específico, como uma tarefa de limpeza noturna.
Formato Melhor Para Capacidade chave
Método futuro Chamadas simples Dispare e esqueça
Apex enfileirado Processamento sequencial Encadeamento e monitoramento de tarefas
Batch Apex Milhões de registros Processamento em blocos
Ápice programado Tarefas recorrentes Temporização baseada em cron

Independentemente do modelo de execução escolhido, todas as transações continuam sendo avaliadas em relação aos limites de governança da plataforma listados abaixo.

Limites do Governador Apex

Os limites de governança do Apex são limites impostos pelo mecanismo de tempo de execução do Apex para garantir que nenhum código ou processo Apex descontrolado monopolize os recursos compartilhados e não interrompa o processamento de outros usuários no ambiente multilocatário. Esses limites são verificados em cada transação do Apex. A seguir, estão os limites de governança definidos pela Salesforce para cada transação do Apex:

Descrição Limitar
Consultas SOQL que podem ser feitas em uma transação síncrona 100
Consultas SOQL que podem ser feitas em uma transação assíncrona 200
Registros que podem ser recuperados por uma consulta SOQL 50,000
Registros que podem ser recuperados por Database.getQueryLocator 10,000
Consultas SOSL que podem ser feitas em uma transação Apex. 20
Registros que podem ser recuperados por uma consulta SOSL 2,000
Instruções DML que podem ser executadas em uma transação Apex. 150
Registros que podem ser processados ​​como resultado de uma instrução DML, Approval.process ou database.emptyRecycleBin 10,000
Chamadas que podem ser feitas em uma transação Apex 100
Limite de tempo limite cumulativo em todas as chamadas externas que estão sendo realizadas em uma transação Apex. 120 segundos
Limite de tarefas Apex que podem ser adicionadas à fila com System.enqueueJob 50
Limite de tempo de execução para cada transação Apex 10 minutos
Limite de caracteres que podem ser usados ​​em uma classe Apex e gatilho 1 milhões
Limite de tempo de CPU para uma transação síncrona 10,000 milissegundos
limite de tempo de CPU para uma transação assíncrona 60,000 milissegundos
Tamanho total do heap 6 MB (síncrono) / 12 MB (assíncrono)

Como escrever uma classe de teste em Apex

A Salesforce exige que pelo menos 75% do seu código Apex seja coberto por testes unitários antes de ser implantado em produção, e cada gatilho deve ter alguma cobertura. Portanto, escrever classes de teste é uma habilidade essencial do Apex, não um extra opcional.

Uma classe de teste é anotada com @isTest, e cada método de teste também é marcado com @isTest. Os métodos de teste não gravam dados no banco de dados e não têm acesso à maioria dos dados existentes da organização; portanto, cada teste cria seus próprios registros. Os métodos Test.startTest() e Test.stopTest() fornecem ao código em teste um novo conjunto de limites de governança, e as asserções verificam se a lógica se comportou conforme o esperado.

Aqui está uma classe de teste simples para a lógica de criação de conta:

@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);
    }
}

Siga estas orientações ao elaborar testes:

  • Utilize o método @testSetup para criar dados de teste compartilhados uma única vez para todos os métodos de teste da classe.
  • Teste o comportamento em lote inserindo 200 registros, e não apenas um.
  • Abrange cenários positivos, negativos e de usuário restrito.
  • Inclua sempre declarações System.assert significativas; cobertura sem asserções não prova nada.

Melhores Práticas da Apex

Iniciantes frequentemente escrevem código Apex que funciona para um único registro, mas falha em operações em massa no mundo real. As práticas abaixo mantêm seu código dentro dos limites de recursos e facilitam a manutenção:

  • Organize tudo em lote: Escreva uma lógica que lide com coleções de registros, pois os gatilhos podem receber até 200 registros em um único lote.
  • Mantenha SOQL e DML fora dos loops: Realize uma consulta antes do loop, colete as alterações em uma lista e execute uma instrução DML após o loop.
  • Um gatilho por objeto: Mantenha os gatilhos sem lógica e delegue o trabalho às classes de tratamento, o que torna a ordem de execução previsível.
  • Use com compartilhamento: Imponha segurança em nível de registro, a menos que haja um motivo documentado para executar no contexto do sistema.
  • Evite inserir IDs diretamente no código: Os IDs de registro diferem entre os ambientes de teste (sandbox) e de produção, portanto, consulte-os ou use metadados personalizados.
  • Monitorar limites no código: Os métodos da classe Limits, como Limits.getQueries(), permitem verificar o consumo de recursos em tempo de execução.

💡 Dica: Execute seu código em 200 registros em um ambiente de teste (sandbox) antes de implantá-lo. A maioria das falhas de limite de recursos (governant limit) ocorre apenas em volumes grandes, e detectá-las precocemente é muito mais barato do que depurá-las em produção.

Perguntas Frequentes

Não. A Apex toma emprestado. JavaA sintaxe é semelhante à do SOQL, mas não diferencia maiúsculas de minúsculas, funciona apenas na plataforma Salesforce Lightning, integra o SOQL diretamente à linguagem e é regida por limites por transação. Java não tem.

Inscreva-se para obter uma organização gratuita do Salesforce Developer Edition, que inclui o Developer Console, e participe de exercícios práticos em Trailhead, a plataforma oficial de aprendizagem da Salesforce.

Visualforce é uma linguagem de marcação para construir páginas de interface de usuário, enquanto Apex é a linguagem do lado do servidor que fornece a lógica por trás delas. As páginas Visualforce frequentemente chamam classes de controlador Apex para consultar e atualizar dados.

Sim. Travas deslizantes portáteis Agentforce para desenvolvedores, o assistente de IA da Salesforce para Visual Studio Code, gera e explica Apex a partir de comandos em linguagem natural. Sempre revise e teste o código gerado por IA em relação aos limites de governança antes de implantá-lo.

As classes Apex marcadas com a anotação @InvocableMethod podem ser expostas como ações personalizadas, permitindo que bots do Einstein e agentes do Agentforce chamem sua lógica de negócios, enquanto o Apex também pode invocar modelos de prompts e modelos de IA do Einstein por meio de APIs da plataforma.

Resuma esta postagem com: