Serviços da Web do Apex

Objetivos de aprendizagem

Após concluir este módulo, você estará apto a:
  • Descrever os dois tipos de serviços da Web do Apex e apresentar um panorama completo desses serviços.
  • Criar uma classe REST do Apex que contenha métodos para cada método HTTP.
  • Invocar um método REST do Apex personalizado com um ponto de extremidade.
  • Passar dados para um método REST do Apex personalizado enviando um corpo de solicitação em formato JSON.
  • Escrever um método de teste para um método REST do Apex e configurar as propriedades de uma solicitação REST de teste.
  • Escrever um método de teste para um método REST do Apex chamando-o com valores de parâmetro.

Expor sua classe do Apex como um serviço da Web

É possível expor seus métodos de classe do Apex como uma operação do serviço da Web REST ou SOAP. Ao possibilitar que seus métodos sejam chamados pela Web, seus aplicativos externos conseguem fazer uma integração com o Salesforce para realizar diversas operações interessantes.

Por exemplo: digamos que a central de atendimento telefônico da sua empresa esteja usando um aplicativo interno para gerenciar os recursos existentes nas instalações. Espera-se que os representantes de atendimento ao cliente usem o mesmo aplicativo para fazer o trabalho diário, o que inclui a gestão dos registros de caso no Salesforce. Ao usar uma única interface, esses representantes conseguem visualizar e atualizar os registros de caso, além de acessar os recursos internos. O aplicativo faz uma chamada para uma classe de serviço da Web do Apex para gerenciar os registros de caso do Salesforce.

Expor uma classe como um serviço REST

É fácil deixar sua classe do Apex disponível como um serviço  da Web REST. Defina sua classe como global e seus métodos como estáticos globais. Acrescente anotações nas classes e nos métodos. Por exemplo: esta classe de exemplo REST do Apex usa um método. O método getRecord é uma chamada API REST personalizada. Ele contém uma anotação de @HttpGet e é invocado para uma solicitação GET.

@RestResource(urlMapping='/Account/*')
global with sharing class MyRestResource {
    @HttpGet
    global static Account getRecord() {
        // Add your code
    }
}

Conforme podemos ver, a classe tem a anotação @RestResource(urlMapping='/Account/*'). O ponto de extremidade de base REST do Apex é https://suaInstância.salesforce.com/services/apexrest/. O mapeamento da URL é acrescentado ao ponto de extremidade de base para formar o ponto de extremidade do seu serviço REST. Por exemplo: no caso da classe, o ponto de extremidade REST é https://suaInstância.salesforce.com/services/apexrest/. Para a sua organização, pode ser algo semelhante a isto:https://suaInstância.salesforce.com/services/apexrest/Account/*.

O mapeamento da URL diferencia maiúsculas de minúsculas e pode conter um caractere curinga (*).

Defina cada método exposto como estático global e acrescente uma anotação para associá-lo a um método HTTP. Estão disponíveis as anotações a seguir. É possível usar cada anotação apenas uma vez em cada classe do Apex.

Anotação Ação Detalhes
@HttpGet Ler Lê ou recupera registros.
@HttpPost Create Cria registros.
@HttpDelete Delete Exclui registros.
@HttpPut Inserir e atualizar (upsert) Costuma ser usado para atualizar registros existentes ou criar registros.
@HttpPatch Update Costuma ser usado para atualizar campos em registros existentes.

Expor uma classe como um serviço SOAP

Também é fácil deixar sua classe do Apex disponível como um serviço da Web SOAP, assim como faria com REST. Defina sua classe como global. Adicione a palavra-chave serviço da Web e o modificador de definição estático a cada método que quiser expor. A palavra-chave serviço da Web permite acesso global ao método ao qual ela foi adicionada.

Por exemplo: aqui está uma classe de exemplo com um método. O método getRecord é uma chamada API SOAP personalizada que devolve um registro de conta.

global with sharing class MySOAPWebService {
    webservice static Account getRecord(String id) {
        // Add your code
    }
}

O aplicativo externo pode chamar seus métodos personalizados do Apex como operações de serviços da Web consumindo o arquivo WSDL de classe. Gere esse WSDL para sua classe a partir da página de detalhes da classe, que pode ser acessada em Configuração, na página Classes do Apex. Em geral, você enviará o arquivo WSDL para desenvolvedores de terceiros (ou fará uso dele pessoalmente) para escrever integrações para seu serviço da Web.

Já que a segurança da plataforma é uma prioridade no Salesforce, seu serviço da Web precisará ser autenticado. Além da WSDL de classe do Apex, os aplicativos externos precisarão usar a Enterprise WSDL ou a Partner WSDL para a funcionalidade de login.

Guia passo a passo de REST do Apex

Chegamos na parte divertida. As próximas etapas mostrarão um passo a passo de como construir um serviço REST do Apex. Em primeiro lugar, você cria a classe do Apex que será exposta como um serviço REST. Depois, tenta chamar alguns métodos de um cliente e finalmente escreve os testes de unidade. É bastante código, mas vai valer a pena!

A sua classe do Apex gerencia os registros de caso. Essa classe contém cinco métodos, e cada método corresponde a um método HTTP. Por exemplo: quando o aplicativo cliente invoca uma chamada REST para o método HTTP GET, o método getCaseById é invocado.

Como a classe é definida com um mapeamento de URL de /Cases/*, o ponto de extremidade usado para chamar esse serviço REST será qualquer URI iniciada por https://suaInstância.salesforce.com/services/apexrest/Cases/.

Sugerimos que você também considere a possibilidade de criar versões para os pontos de extremidade da sua API para poder oferecer melhorias de funcionalidade sem estragar o código existente. Você pode criar duas classes especificando os mapeamentos de URL de /Cases/v1/* e /Cases/v2/* a fim de implementar essa funcionalidade.

Comecemos criando uma classe REST do Apex.

  1. Abra o Developer Console na engrenagem de configurações (Ícone de engrenagem de configuração).
  2. No Developer Console, selecione File (Arquivo) | New (Novo) | Apex Class (Classe do Apex).
  3. Para o nome da classe, insira CaseManager e clique em OK.
  4. Substitua o código gerado automaticamente pela seguinte definição de classe.
    @RestResource(urlMapping='/Cases/*')
    global with sharing class CaseManager {
    
        @HttpGet
        global static Case getCaseById() {
            RestRequest request = RestContext.request;
            // grab the caseId from the end of the URL
            String caseId = request.requestURI.substring(
              request.requestURI.lastIndexOf('/')+1);
            Case result =  [SELECT CaseNumber,Subject,Status,Origin,Priority
                            FROM Case
                            WHERE Id = :caseId];
            return result;
        }
    
        @HttpPost
        global static ID createCase(String subject, String status,
            String origin, String priority) {
            Case thisCase = new Case(
                Subject=subject,
                Status=status,
                Origin=origin,
                Priority=priority);
            insert thisCase;
            return thisCase.Id;
        }   
    
        @HttpDelete
        global static void deleteCase() {
            RestRequest request = RestContext.request;
            String caseId = request.requestURI.substring(
                request.requestURI.lastIndexOf('/')+1);
            Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId];
            delete thisCase;
        }     
    
        @HttpPut
        global static ID upsertCase(String subject, String status,
            String origin, String priority, String id) {
            Case thisCase = new Case(
                    Id=id,
                    Subject=subject,
                    Status=status,
                    Origin=origin,
                    Priority=priority);
            // Match case by Id, if present.
            // Otherwise, create new case.
            upsert thisCase;
            // Return the case ID.
            return thisCase.Id;
        }
    
        @HttpPatch
        global static ID updateCaseFields() {
            RestRequest request = RestContext.request;
            String caseId = request.requestURI.substring(
                request.requestURI.lastIndexOf('/')+1);
            Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId];
            // Deserialize the JSON string into name-value pairs
            Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(request.requestbody.tostring());
            // Iterate through each parameter field and value
            for(String fieldName : params.keySet()) {
                // Set the field and value on the Case sObject
                thisCase.put(fieldName, params.get(fieldName));
            }
            update thisCase;
            return thisCase.Id;
        }    
    
    }
  5. Pressione Ctrl+S para salvar.

Como criar um registro com um método POST

Vamos usar a classe REST do Apex que você acabou de criar para nos divertirmos um pouco. Primeiro, vamos chamar o método POST para criar um registro de caso.

Para invocar o serviço REST, você precisará usar um... cliente REST! É possível usar praticamente qualquer cliente REST, como o seu próprio cliente API, a ferramenta de linha de comando cURL ou a biblioteca cURL para PHP. Usaremos a ferramenta Workbench como nosso aplicativo cliente REST, mas depois veremos como funcionaria com cURL.

O REST do Apex dá suporte a dois formatos para representações de recursos: JSON e XML. Por padrão, as representações JSON são passadas no corpo de uma solicitação ou resposta, e o formato é indicado pela propriedade Content-Type do cabeçalho HTTP. Como é mais fácil ler e compreender JSON do que XML, essa unidade usa apenas JSON. Nesta etapa, você enviará um registro de caso no formato JSON.

O REST do Apex oferece suporte a OAuth 2.0 e mecanismos de autenticação de sessão. Para simplificar, isso significa que usamos padrões do setor para manter seu aplicativo e seus dados em segurança. Por sorte, você poderá usar o Workbench para facilitar os testes. O Workbench é um poderoso conjunto de ferramentas da Web para os administradores e desenvolvedores interagirem com as organizações por meio das APIs da Lightning Platform. Com o Workbench, você usa sua autenticação de sessão ao fazer o login com seu nome de usuário e senha no Salesforce. Depois, usa o Explorador REST para chamar seu serviço REST.

  1. Navegue para https://workbench.developerforce.com/login.php.
  2. Em Ambiente, selecione Production (Produção).
  3. Selecione a última versão da API no menu suspenso API Version (Versão da API).
  4. Aceite os termos de serviço e clique em Login with Salesforce (Fazer login com o Salesforce).
  5. Para permitir que o Workbench acesse suas informações, clique em Allow (Permitir).
  6. Digite suas credenciais de login e clique em Log in to Salesforce (Fazer login no Salesforce).
  7. Após fazer o login, selecione Utilities (Utilitários) | REST Explorer (Explorador REST).
  8. Selecione POST.
  9. O caminho da URL que o Explorador REST aceita depende da URL de instância da sua organização. Indique apenas o caminho relacionado à URL de instância. No campo de entrada da URI em questão, troque a URI padrão por /services/apexrest/Cases/.
  10. Para o corpo da solicitação, insira a seguinte representação de sequência de caracteres JSON do objeto que será inserido.
    {
      "subject" : "Bigfoot Sighting!",
      "status" : "New",
      "origin" : "Phone",
      "priority" : "Low"
    }
  11. Clique em Execute (Executar).
    Essa invocação chama o método associado ao HTTP POST, mais especificamente o método createCase.
  12. Para ver a resposta devolvida, clique em Show Raw Response (Exibir resposta bruta).
    A resposta devolvida será mais ou menos assim. Ela conterá a ID do novo registro de caso. Seu valor de ID provavelmente não será 50061000000t7kYAAQ. Salve seu valor de ID para utilizá-lo nas próximas etapas.
    HTTP/1.1 200 OK
    Date: Wed, 07 Oct 2015 14:18:20 GMT
    Set-Cookie: BrowserId=F1wxIhHPQHCXp6wrvqToXA;Path=/;Domain=.salesforce.com;Expires=Sun, 06-Dec-2015 14:18:20 GMT
    Expires: Thu, 01 Jan 1970 00:00:00 GMT
    Content-Type: application/json;charset=UTF-8
    Content-Encoding: gzip
    Transfer-Encoding: chunked
    
    "50061000000t7kYAAQ" 

Recuperar dados com um método GET personalizado

Ao seguir passos parecidos com os anteriores, use o Workbench para invocar o método HTTP GET.

  1. No Workbench, selecione GET.
  2. Insira a URI /services/apexrest/Cases/<>, trocando <> pela ID do registro que você criou na etapa anterior.
  3. Clique em Execute (Executar).

    Essa invocação chama o método associado ao HTTP GET, mais especificamente o método getCaseById.

  4. Para ver a resposta devolvida, clique em Show Raw Response (Exibir resposta bruta).

    A resposta devolvida será mais ou menos assim. Ela conterá os campos que o método pesquisou para o novo registro de caso.

    HTTP/1.1 200 OK
    Date: Wed, 07 Oct 2015 14:28:20 GMT
    Set-Cookie: BrowserId=j5qAnPDdRxSu8eHGqaRVLQ;Path=/;Domain=.salesforce.com;Expires=Sun, 06-Dec-2015 14:28:20 GMT
    Expires: Thu, 01 Jan 1970 00:00:00 GMT
    Content-Type: application/json;charset=UTF-8
    Content-Encoding: gzip
    Transfer-Encoding: chunked
    
    {
      "attributes" : {
        "type" : "Case",
        "url" : "/services/data/v34.0/sobjects/Case/50061000000t7kYAAQ"
      },
      "CaseNumber" : "00001026",
      "Subject" : "Bigfoot Sighting!",
      "Status" : "New",
      "Origin" : "Phone",
      "Priority" : "Low",
      "Id" : "50061000000t7kYAAQ"
    }
    

Recuperar dados usando cURL

Todo desenvolvedor que se preze deve saber pelo menos três coisas: 1) como criar um GIF animado de si mesmo tomando sorvete; 2) o valor de pi à 25ª potência; e 3) como usar cURL. Os dois primeiros itens não fazem parte do escopo deste módulo, motivo pelo qual vamos nos concentrar no último.

A cURL é uma ferramenta de linha de comando usada para obter ou enviar arquivos usando a sintaxe das URLs. Ela é muito útil ao trabalhar com pontos de extremidade REST. Em vez de usar o Workbench para seu serviço REST do Apex, você usa a cURL para invocar o método HTTP GET. Toda vez que você aplica a cURL ao seu ponto de extremidade REST, você faz a passagem da ID da sessão para autorização. Fomos todos mimados pelo Workbench porque ele faz a passagem da ID da sessão por nós, em segundo plano, após o login.

Para obter uma ID de sessão, primeiro crie um aplicativo conectado em sua organização do Salesforce e ative o OAuth. Seu aplicativo cliente, a cURL nesse caso, usa o aplicativo conectado para se conectar ao Salesforce. Siga essas instruções para criar um aplicativo conectado que forneça a chave do cliente e o segredo do cliente que você precisa para obter a ID da sessão. Ao selecionar os escopos de OAuth para seu aplicativo conectado, escolha o escopo “Acessar e gerenciar seus dados (api)”. Pode demorar de 5 a 10 minutos para o aplicativo conectado concluir a configuração. Quando estiver pronto, use o seguinte comando da cURL com suas credenciais e o aplicativo conectado.

Use sua ferramenta de linha de comando preferida para executar essas solicitações, como o Terminal no macOS/Linux ou o Prompt de comando no Windows.

curl -v https://login.salesforce.com/services/oauth2/token -d "grant_type=password" -d "client_id=<your_consumer_key>" -d "client_secret=<your_consumer_secret>" -d "username=<your_username>" -d "password=<your_password_and_security_token>" -H 'X-PrettyPrint:1'

Se tudo correr bem, o resultado incluirá um access_token que é sua ID de sessão e instance_url para sua organização.

Resposta da cURL com o token de acesso

Agora, insira seu comando da cURL, que será semelhante ao que exibimos a seguir, para ligar para o serviço REST do Apex e devolver a informação do caso.

curl https://yourInstance.salesforce.com/services/apexrest/Cases/<Record_ID> -H 'Authorization: Bearer <your_session_id>' -H "X-PrettyPrint:1"

Após pressionar Enter, você verá algo parecido com o que vemos a seguir. Agora que você dominou as linhas de comando com maestria, fique à vontade para usar cURL, jq, sed, awk e grep como bem entender. Para mais informações sobre cURL, consulte a seção Recursos.

cURL e resposta da linha de comando

Atualizar dados com os métodos personalizados PUT ou PATCH

É possível atualizar registros com os métodos HTTP PUT ou PATCH. O método PUT atualiza o recurso inteiro, caso ele já exista, ou cria um recurso que ainda não exista. O PUT é basicamente um método de inserir e atualizar. O método PATCH atualiza apenas partes específicas de um recurso que já existe. No Apex, as operações de atualização modificam apenas os campos especificados e não sobrescrevem o registro inteiro. Escreveremos alguns códigos do Apex para determinar se nossos métodos fazem atualização ou inserção e atualização.

Atualizar dados com o método PUT

O método upsertCase que você adicionou à classe CaseManager implementa a ação PUT. Esse método está aqui para sua consulta. Ele usa o método DML integrado de upsert do Apex para criar ou sobrescrever campos de um registro de caso por meio de uma correspondência com o valor da ID. Quando uma ID é enviada no corpo da solicitação, o sObject do caso é preenchido com ela. Em contrário, o sObject do caso é criado sem uma ID. O método upsert é invocado com o sObject do caso preenchido, e o demonstrativo DML cuida do restante. Tcharam!

@HttpPut
global static ID upsertCase(String subject, String status,
    String origin, String priority, String id) {
    Case thisCase = new Case(
        Id=id,
        Subject=subject,
        Status=status,
        Origin=origin,
        Priority=priority);
    // Match case by Id, if present.
    // Otherwise, create new case.
    upsert thisCase;
    // Return the case ID.
    return thisCase.Id;
}
Para invocar o método PUT:
  1. No Explorador REST do Workbench, selecione PUT.
  2. Na URI, insira /services/apexrest/Cases/.
  3. O método upsertCase espera que os valores de campo sejam passados no corpo da solicitação. Adicione as informações a seguir para o corpo da solicitação e troque <Record ID> pela ID do registro de caso que você criou agora há pouco.
    {
      "id": "<Record_ID>",
      "status" : "Working",
      "subject" : "Bigfoot Sighting!",
      "priority" : "Medium"
    }
    Nota

    Nota

    O campo da ID é opcional. Para criar um registro de caso, omita esse campo. No nosso exemplo, você está passando esse campo porque pretende atualizar o registro de caso.

  4. Clique em Execute (Executar).

    Essa solicitação invoca o método upsertCase do seu serviço REST. Os campos Estado, Assunto e Prioridade são atualizados. O assunto é atualizado, mesmo se o valor for igual ao do assunto antigo. Além disso, uma vez que o corpo da solicitação não continha um valor para o campo Origem do caso o parâmetro origem do método upsertCase será nulo. Em decorrência disso, o campo Origem ficará em branco quando o registro for atualizado.

    Para conferir esses campos, veja esse registro no Salesforce navegando para https://suaInstância.salesforce.com/<Record ID>.

Atualizar dados com o método PATCH

Outra opção é usar o método PATCH, não PUT, para atualizar os campos de registro. É possível implementar o método PATCH de várias formas. Uma delas é especificar os parâmetros do método para cada campo que será atualizado. Por exemplo: você poderá criar um método que atualizará a prioridade de um caso com esta assinatura: updateCasePriority(String priority). Para atualizar diversos campos, é possível listar todos os campos desejados como parâmetros.

Outra abordagem que gera mais flexibilidade é passar os campos como pares de nome/valor JSON no corpo da solicitação. Dessa forma, o método poderá aceitar um número arbitrário de parâmetros, e os parâmetros não serão fixos na assinatura do método. Outro ponto positivo dessa abordagem é que nenhum campo ficará em branco por engano só por ser nulo. O método updateCaseFields que você adicionou à classe CaseManager usa essa segunda abordagem. Esse método elimina a serialização da sequência de caracteres JSON do corpo da solicitação, transformando-a em um mapa de pares de nome/valor, e usa o método PUT do sObject para configurar os campos.

@HttpPatch
global static ID updateCaseFields() {
    RestRequest request = RestContext.request;
    String caseId = request.requestURI.substring(
        request.requestURI.lastIndexOf('/')+1);
    Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId];
    // Deserialize the JSON string into name-value pairs
    Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(request.requestbody.tostring());
    // Iterate through each parameter field and value
    for(String fieldName : params.keySet()) {
        // Set the field and value on the Case sObject
        thisCase.put(fieldName, params.get(fieldName));
    }
    update thisCase;
    return thisCase.Id;
}
Para invocar o método PATCH:
  1. No Explorador REST do Workbench, clique em PATCH.
  2. Na URI, insira /services/apexrest/Cases/<Record ID>. Troque o <Record ID> pela ID do registro de caso criada agora há pouco. Insira o seguinte JSON no corpo da solicitação.
    {
      "status" : "Escalated",
      "priority" : "High"
    }

    Esse JSON tem dois valores de campo: status e prioridade. O método updateCaseFields recupera esses valores do JSON enviado e é usado para especificar os campos que serão atualizados no objeto.

  3. Clique em Execute (Executar).

    Essa solicitação invoca o método updateCaseFields do seu serviço REST. Os campos Estado e Prioridade do registro de caso são atualizados para os novos valores. Para conferir esses campos, veja esse registro no Salesforce navegando para https://suaInstância.salesforce.com/<Record ID>.

Testar sua classe REST do Apex

Testar sua classe REST do Apex é como testar qualquer outra classe do Apex: basta chamar os métodos de classe passando os valores de parâmetro e conferindo os resultados. Para os métodos que não precisam de parâmetros ou que utilizam as informações da solicitação REST, crie uma solicitação REST de teste.

De forma geral, é assim que os serviços REST do Apex são testados. Para simular uma solicitação REST, crie uma RestRequest no método de teste e configure as propriedades da solicitação conforme as instruções abaixo. Também é possível adicionar parâmetros que sejam “passados” na solicitação para simular os parâmetros URI.

// Set up a test request
RestRequest request = new RestRequest();

// Set request properties
request.requestUri =
    'https://yourInstance.salesforce.com/services/apexrest/Cases/'
    + recordId;
request.httpMethod = 'GET';

// Set other properties, such as parameters
request.params.put('status', 'Working');

// more awesome code here....
// Finally, assign the request to RestContext if used
RestContext.request = request;

Se o método que você está testando acessar os valores da solicitação através de RestContext, atribua a solicitação a RestContext para preenchê-lo (RestContext.request = request;).

Agora, vamos salvar essa classe inteira no Developer Console e executar os resultados.

  1. No Developer Console, selecione File (Arquivo) | New (Novo) | Apex Class (Classe do Apex).
  2. Para o nome da classe, insira CaseManagerTest e clique em OK.
  3. Substitua o código gerado automaticamente pela seguinte definição de classe.
    @IsTest
    private class CaseManagerTest {
    
        @isTest static void testGetCaseById() {
            Id recordId = createTestRecord();
            // Set up a test request
            RestRequest request = new RestRequest();
            request.requestUri =
                'https://yourInstance.salesforce.com/services/apexrest/Cases/'
                + recordId;
            request.httpMethod = 'GET';
            RestContext.request = request;
            // Call the method to test
            Case thisCase = CaseManager.getCaseById();
            // Verify results
            System.assert(thisCase != null);
            System.assertEquals('Test record', thisCase.Subject);
        }
    
        @isTest static void testCreateCase() {
            // Call the method to test
            ID thisCaseId = CaseManager.createCase(
                'Ferocious chipmunk', 'New', 'Phone', 'Low');
            // Verify results
            System.assert(thisCaseId != null);
            Case thisCase = [SELECT Id,Subject FROM Case WHERE Id=:thisCaseId];
            System.assert(thisCase != null);
            System.assertEquals(thisCase.Subject, 'Ferocious chipmunk');
        }
    
        @isTest static void testDeleteCase() {
            Id recordId = createTestRecord();
            // Set up a test request
            RestRequest request = new RestRequest();
            request.requestUri =
                'https://yourInstance.salesforce.com/services/apexrest/Cases/'
                + recordId;
            request.httpMethod = 'GET';
            RestContext.request = request;
            // Call the method to test
            CaseManager.deleteCase();
            // Verify record is deleted
            List<Case> cases = [SELECT Id FROM Case WHERE Id=:recordId];
            System.assert(cases.size() == 0);
        }
    
        @isTest static void testUpsertCase() {
            // 1. Insert new record
            ID case1Id = CaseManager.upsertCase(
                    'Ferocious chipmunk', 'New', 'Phone', 'Low', null);
            // Verify new record was created
            System.assert(Case1Id != null);
            Case case1 = [SELECT Id,Subject FROM Case WHERE Id=:case1Id];
            System.assert(case1 != null);
            System.assertEquals(case1.Subject, 'Ferocious chipmunk');
            // 2. Update status of existing record to Working
            ID case2Id = CaseManager.upsertCase(
                    'Ferocious chipmunk', 'Working', 'Phone', 'Low', case1Id);
            // Verify record was updated
            System.assertEquals(case1Id, case2Id);
            Case case2 = [SELECT Id,Status FROM Case WHERE Id=:case2Id];
            System.assert(case2 != null);
            System.assertEquals(case2.Status, 'Working');
        }    
    
        @isTest static void testUpdateCaseFields() {
            Id recordId = createTestRecord();
            RestRequest request = new RestRequest();
            request.requestUri =
                'https://yourInstance.salesforce.com/services/apexrest/Cases/'
                + recordId;
            request.httpMethod = 'PATCH';
            request.addHeader('Content-Type', 'application/json');
            request.requestBody = Blob.valueOf('{"status": "Working"}');
            RestContext.request = request;
            // Update status of existing record to Working
            ID thisCaseId = CaseManager.updateCaseFields();
            // Verify record was updated
            System.assert(thisCaseId != null);
            Case thisCase = [SELECT Id,Status FROM Case WHERE Id=:thisCaseId];
            System.assert(thisCase != null);
            System.assertEquals(thisCase.Status, 'Working');
        }  
    
        // Helper method
        static Id createTestRecord() {
            // Create test record
            Case caseTest = new Case(
                Subject='Test record',
                Status='New',
                Origin='Phone',
                Priority='Medium');
            insert caseTest;
            return caseTest.Id;
        }          
    
    }
  4. Pressione Ctrl+S para salvar.
  5. Execute todos os testes da sua organização selecionando Test (Teste) | Run All (Executar todos).

Os resultados do teste serão exibidos na guia Testes. Quando a execução do teste terminar, confira a linha CaseManager no painel Cobertura de código geral. Ela estará com uma cobertura de 100%.

Quero saber mais...

Saiba mais sobre os tipos de dados e namespaces que são aceitos no REST do Apex, no Salesforce, nas APIs e nas considerações de segurança.
Tipos de dados aceitos no REST do Apex
O REST do Apex aceita os seguintes tipos de dados para parâmetros e valores de retorno.
  • Números primitivos do Apex (à exceção de sObject e Blob).
  • sObjects;
  • Listas ou mapas de números primitivos ou sObjects do Apex (suporte apenas para os mapas com chaves de sequência de caracteres).
  • Tipos definidos pelo usuário que contenham variáveis de membro dos tipos listados acima.
Namespaces em pontos de extremidade REST do Apex
Os métodos REST do Apex podem ser usados em pacotes gerenciados e não gerenciados. Ao chamar os métodos REST do Apex que fazem parte de um pacote gerenciado, você precisará incluir o namespace do pacote gerenciado na URL de chamada REST. Por exemplo: quando a classe faz parte do namespace de um pacote gerenciado chamado packageNamespace e os métodos REST do Apex usam um mapeamento de URL de /MyMethod/*, a URL usada via REST para chamar esses métodos teria o formato https://instância.salesforce.com/services/apexrest/packageNamespace/MyMethod/.
Serviços da web do Apex personalizados e APIs do Salesforce
Em vez de usar códigos personalizados do Apex para os serviços REST e SOAP, os aplicativos externos podem fazer uma integração com o Salesforce usando as APIs REST e SOAP do Salesforce. Essas APIs possibilitam a criação, atualização e exclusão de registros. Contudo, a vantagem de usar os serviços da Web do Apex é que os métodos do Apex conseguem encapsular uma lógica complexa. Essa lógica fica oculta do aplicativo de consumo. Além disso, as operações de classe do Apex podem ser mais rápidas em comparação com chamadas individuais para cada API, porque é necessário executar menos trajetos de ida e volta entre o cliente e os servidores do Salesforce. Com uma chamada de serviço da Web do Apex, apenas uma solicitação é enviada, e todas as operações incluídas no método são realizadas no servidor.
Considerações de segurança para os serviços da Web do Apex
O contexto de segurança em que os métodos de serviço da Web do Apex são executados é diferente do contexto de segurança das APIs do Salesforce. Ao contrário das APIs do Salesforce, os métodos de serviços da Web do Apex são executados com privilégios do sistema e não estão sujeitos às permissões de objeto e campo do usuário. No entanto, os métodos de serviço da Web do Apex impõem regras de compartilhamento quando são declarados com a palavra-chave com compartilhamento.