Neste post vamos juntos mergulhar a fundo e entender todas as opções disponíveis na REST API do Salesforce, vamos sair da teoria a prática, e finalizar com um teste, espero que depois de ler este post, você tenha todo o entendimento necessário para cria a sua própria REST customizada.
Mas afinal o que é uma REST?
A Representational State Transfer (REST), é uma forma de expor acesso a dados de uma aplicação GET, e também permite receber dados POST/PUT/PATCH ou até mesmo remover um dado DELETE. Basicamente é possível fazer um CRUD (Create, Read, Update e Delete) utilizando apenas REST. Como prometido vou tentar mergulhar fundo na utilização de REST API, mas ainda assim sugiro que você dê uma olhada neste e também neste módulo do trailhead, afinal é sempre bom ganhar algumas badges não é mesmo?
Entendendo os Annotation do Salesforce para REST API
Para criar sua REST customizada no Salesforce, vamos precisar fazer uso de alguns Annotations do Apex, são eles:
- @RestResource(urlMapping=‘/nomeEndpoint’)
- @HttpDelete
- @HttpGet
- @HttpPatch
- @HttpPost
- @HttpPut
Digo REST customizada, porque o Salesforce oferece RESTs padrões para todos os objetos do Salesforce, sejam eles customizados ou não, mas essa discussão vai ficar para outro post, o objetivo hoje é falarmos sobre uma REST totalmente customizada pelo desenvolvedor.
Bom, agora que sabemos quais são os annotations e o que é uma REST, vamos entender para que serve cada uma das opções da REST API, vamos lá?
@RestResource serve para mapear um endereço de serviço no Salesforce. A sua classe do Apex deve ser obrigatoriamente uma classe Global, e a anotação deve estar acima da declaração da sua classe.
@RestResource(urlMapping='/Eventos') global class ListEventoREST { }
Em linhas gerais, somente o annotation @RestResource, tem uma função específica, todos os demais, apesar de terem seus nomes bem definidos, não necessariamente precisam ser utilizados somente para aquele propósito, ou seja, nada vai te impedir de fazer a criação de um registro utilizando um método assinado com @HttpDelete, mas claro, vamos ser sensatos e tentar utilizar o padrão, seus colegas desenvolvedores vão agradecer, além do que, isso permitirá que sua aplicação cresça de forma saudável e sustentável, tenho certeza que você é um bom desenvolvedor e não fará uma aberração dessa com o seu código, não é mesmo?
Então vamos entender as demais annotations.
@HttpDelete, deve ser utilizado para remover um registro, para você recuperar os parâmetros enviados, você deve recuperar-los fazendo um GET no MAP de parâmetros recebidos no RestContext.
@HttpDelete global static void toDelete() { Id id = RestContext.request.params.get('Id'); //TODO: Implement your code here! }
@HttpGet, permite retornar dados através de uma requisição GET, assim como o DELETE, o GET deve ler os parâmetros enviados através do RestContext.
@HttpGet global static Account getAccountDetail() { Id accountId = RestContext.request.params.get('Id'); Account account; //TODO: Implement your code here! //account = [SELECT Id, Name FROM Account WHERE Id = :accountId]; return account; }
@HttpPatch, permite receber os dados que serão atualizados, você pode especificar no seu método, quais parâmetros deseja receber.
@HttpPatch global static Account updateAccount(Account account) { //TODO: Implement your code here! //update account; return account; }
@HttpPost, permite receber os dados que serão criados, você poderá especificar no seu método, quais parâmetros deseja receber.
@HttpPost global static Account insertAccount(Account account) { //TODO: Implement your code here! //insert account; return account; }
E por fim, o @HttpPut, este seria como o Upsert do SOQL, permitindo receber dados que serão criados ou atualizados, você pode especificar no seu método, quais parâmetros deseja receber.
@HttpPut global static Account upsertAccount(Account account) { //TODO: Implement your code here! //upsert account; return account; }
REST API na vida real
Já precisei utilizar REST para fazer integração entre um aplicativo Android com o Salesforce, e também para fazer o Download de um arquivo e exibir no Browser para o usuário, e foi com base nesses cenários, que veio a ideia deste post, se você precisar integrar um sistema ao Salesforce, muito provavelmente deverá fazer isso via REST, então, entender como criar uma REST, irá te trazer uma boa bagagem para futuras integrações.
Objetivo do exercício
Para entendermos como criar uma REST customizada, vamos criar um cadastro de eventos, e disponibilizar a opção da pessoa se registrar para esse evento via REST API, claro que esse exemplo é apenas para ilustrar a funcionalidade da REST API, pois existem várias outras formas de fazer isso, estou tentando aqui, apenas aguçar a sua criatividade para as inúmeras possibilidades de utilização da REST API do Salesforce.
Criando um objeto customizado no Salesforce
O Salesforce tem duas interfaces de usuário de desktop diferentes: o Lightning Experience e o Salesforce Classic. Este post seguirá utilizando o Lightning Experience.
Você pode saber mais sobre como alternar entre interfaces, como habilitar o Lightning Experience e mais no módulo Noções básicas do Lightning Experience do Trailhead.
Para o nosso exemplo, vamos criar um objeto chamado Evento e adicionar alguns campos personalizados.
- Clique no no ícone de engrenagem e acesse o Setup.
- Pesquise por Object Manager no menu lateral.
- Em seguida clique na opção Create e escolha Custom Object.
- Preencha o campo Label com Evento, Plural Label com Eventos, escolha o Gender como Masculine e deixei o Object Name como Evento mesmo, insira uma descrição para o objeto “Armazena os eventos disponíveis“, altere o Record Name para Nome do Evento e marque o checkbox Allow Reports.
Agora vamos criar 2 campos de Data e Hora, um chamado Inicio e outro Fim.
- Acesse o menu Fields & Relationships e clique no botão New.
- Selecione a opção Date/Time e clique no botão Next.
- Preencha o Label como Inicio, e deixe as outras opções como padrão em seguida clique em Next.
- Deixe os perfis padrões como estão e clique em Next.
- Deixe marcado a opção para adicionar o campo no layout e clique em Save & New.
- Selecione a opção Date/Time e clique no botão Next.
- Preencha o Label como Fim, e deixe as outras opções como padrão em seguida clique em Next.
- Deixe os perfis padrões como estão e clique em Next.
- Deixe marcado a opção para adicionar o campo no layout e clique em Save.
Com os campos criados, podemos partir para o próximo objeto, que será o objeto responsável por coletar os dados que serão manipulados via REST API, vamos chamar esse novo objeto de Participante.
- Clique na aba Object Manager, para retornar a tela inicial do Object Manager.
- Em seguida clique na opção Create e escolha Custom Object.
- Preencha o campo Label com Participante, Plural Label com Participantes, escolha o Gender como Masculine e deixei o Object Name como Participante mesmo, insira uma descrição para o objeto “Lista dos participantes dos eventos“, altere o Record Name para Nome do Participante e marque o checkbox Allow Reports.
Agora vamos criar os campos dos participantes, para esse exemplo vamos criar apenas um campo chamado E-mail, e vamos utilizar o campo padrão Name para ser o nome do Participante, vamos criar também um campo que indicará qual é o Id do Evento que o participante se registrou.
- Acesse o menu Fields & Relationships e clique no botão New.
- Selecione a opção Email e clique no botão Next.
- Preencha o Label como Email, e deixe as outras opções como padrão em seguida clique em Next.
- Deixe os perfis padrões como estão e clique em Next.
- Deixe marcado a opção para adicionar o campo no layout e clique em Save & New.
- Selecione a opção Master-Detail Relationship e clique no botão Next.
- Selecione na opção Related To o objeto Evento e clique em Next.
- Deixe os campos preenchidos como aparecem na tela e clique em Next.
- Deixe os perfis padrões como estão e clique em Next.
- Deixe marcado a opção para adicionar o campo no layout e clique em Save.
Com isso finalizamos a configuração dos nossos objetos, futuramente podemos adicionar um campo no Objeto evento para contar o número de participantes em cada evento, porém isso não afetará a criação da nossa REST, então vamos seguir para o próximo passo, a criação das nossas RESTs, vamos lá?
Criando a sua primeira classe com REST API do Salesforce
O objetivo aqui é tentar ser o mais prático possível, então, vamos deixar vários métodos em uma única classe, mas recomendo fortemente que você separe suas consultas SOQL em uma classe DAO separada da classe de REST API.
A primeira classe que vamos criar, será a classe que listará todos os Eventos cadastrados.
Para isso acesse o Console do desenvolvedor, clicando na Engrenagem em seguida escolhendo a opção Developer Console.
Agora acesse o menu File \ New \ Apex Class e entre com o nome ListEventoREST e clique em OK.
A nossa classe deve ficar conforme a classe abaixo, não esqueça de que a classe e os métodos devem ser definidas como Global, e os métodos como static:
@RestResource(urlMapping='/Eventos') global class ListEventoREST { @HttpGet global static List<Evento__c> getEventos() { return [SELECT Id, Name, Inicio__c, Fim__c FROM Evento__c WHERE Fim__c >= TODAY]; } }
A próxima classe, será a classe de Participante, essa classe será responsável por fazer o nosso CRUD, acesse o menu File \ New \ Apex Class e entre com o nome ParticipanteREST e clique em OK.
A nossa classe deve ficar assim:
@RestResource(urlMapping = '/Participante/*') global class ParticipanteREST { @HttpGet global static Participante__c getParticipante() { Id idParticipante = (Id)RestContext.request.params.get('Id'); try { return [SELECT Id, Name, Email__c, Evento__c, Evento__r.Name FROM Participante__c WHERE Id = :idParticipante]; } catch (Exception ex) { system.debug(ex); RestContext.response.statusCode = 404; return null; } } @HttpPost global static Participante__c newParticipante(Participante__c participante) { insert participante; return participante; } @HttpPut global static Participante__c upsertParticipante(Participante__c participante) { upsert participante; return participante; } @HttpPatch global static Participante__c updateParticipante(Participante__c participante) { update participante; return participante; } @HttpDelete global static void deleteParticipante() { Id idParticipante = (Id)RestContext.request.params.get('Id'); Participante__c participante = new Participante__c(Id = idParticipante); delete participante; } }
Chamando a REST via Workbench
Se você não conhece ainda o Workbench, está na hora de conhecer, ele sem dúvida é o melhor amigo de um Desenvolvedor Salesforce, não vou abordar aqui todas as funções do Workbench, talvez em um post futuro, mas hoje vamos nos concentrar em utilizar ele para consumir as nossas RESTs criadas, o Workbench facilitará o nosso trabalho, pois com ele não precisaremos criar um Aplicativo Conectado do Salesforce nem consumir os dados através de uma ferramenta ou código, vamos deixar isso também para um post futuro.
Vamos lá?
Antes de mais nada, precisamos inserir alguma informação no nosso objeto Evento, para isso, acesse o mesmo no Salesforce e crie um novo registro lá, afinal sem isso não teremos dados para exibir na nossa REST.
O primeiro passo é acessar o site https://workbench.developerforce.com marcar o check box de aceite e clicar em login, você será redirecionado para a tela de login do Salesforce, informe os dados da ORG que você utilizou para criar a sua REST, após logar, você será direcionado para a tela abaixo, clique no menu utilities em seguida na opção REST Explorer.
Fazendo uma requisição GET para listar todos os eventos disponíveis:
Altere a url do campo para /services/apexrest/Eventos e clique no botão Execute
Você verá todos os registros criados no objeto de Eventos, e fizemos isso consumindo o nosso método GET da nossa REST de Eventos.
Copie o Id do seu resultado, pois ele será necessário para realizar o próximo passo.
Fazendo um POST para se cadastrar no evento:
Agora vamos realizar um POST e fazer um cadastro, agora precisamos alterar a url do campo para /services/apexrest/Participante o tipo de requisição para POST e no Request Body inserir o JSON abaixo (não se esqueça de substituir o valor do Id que você copiou na etapa anterior e substituir no campo “Evento__c” do seu JSON):
{ "participante" : { "Evento__c":"a0F1I000001R6JUUA0", "Name":"Fernando Sousa", "Email__c":"[email protected]" } }
Fazendo um PATCH para atualizar o cadastro:
Note que agora você também precisará copiar o Id do resultado anterior, que é o Id do seu participante, e neste caso só precisamos enviar no JSON as informações do Id e os campos que forem ser alterados, no nosso exemplo vamos alterar o email.
{ "participante" : { "Id":"a0G1I000001RhWRUA0", "Email__c":"[email protected]" } }
Fazendo um PUT, também para atualizar o registro:
Importante ressaltar que no nosso caso, enviamos o Id do registro, então ele sofrerá uma alteração, se o Id não for enviado, será feita a inclusão de um novo registro.
{ "participante" : { "Id":"a0G1I000001RhWRUA0", "Email__c":"[email protected]" } }
Fazendo um DELETE:
Por fim o nosso método de remover um registro, neste caso o valor é enviado na URL, devemos então alterar o caminho do serviço com o Id do participante, no nosso exemplo ficando assim: /services/apexrest/Participante?Id=a0G1I000001RhWRUA0
O retorno do DELETE, nada mais é do que um HTTP 200.
Conclusão
O objetivo deste post era te mostrar como criar sua própria REST, passamos pelo entendimento do que é cada uma das opções da REST API, criamos um exemplo prático e finalizamos com o consumo das RESTs, no próximo post vou mostrar como criar uma REST publica, que não exija autenticação para ser consumida, e vou deixar a baixo algumas referências que foram úteis para a construção desse post.
Um forte abraço e até o próximo post ;)
Referências
https://pt.wikipedia.org/wiki/REST
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/
https://developer.salesforce.com/page/Creating_REST_APIs_using_Apex_REST
https://trailhead.salesforce.com/pt-BR/modules/apex_integration_services
https://trailhead.salesforce.com/pt-BR/content/learn/modules/api_basics
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_understanding_username_password_oauth_flow.htm
Fernando Sousa
Senior Salesforce Developer
Bacharel em Sistemas da Informação pela Universidade de Taubaté (UNITAU) e MBA em Projeto de Aplicações para Dispositivos Móveis pelo IGTI – Instituto de Gestão em Tecnologia da Informação.
Comecei a programar bem cedo, por volta de 10 anos de idade, de maneira auto-didata passei por várias linguagens.
Em 2015 me conectei a plataforma Salesforce pela primeira vez, para fazer una integração entre um Aplicativos Mobile em android e o Salesforce Platform.
Atualmente com as certificações Salesforce Certified Platform Developer I, Salesforce Certified Platform App Builder, Salesforce Certified Platform Developer II, Salesforce Administrator e Sharing and Visibility.
Acompanhe meu Trailhead aqui.