Empiece a realizar un seguimiento de su progreso
Inicio de Trailhead
Inicio de Trailhead

Servicios web Apex

Objetivos de aprendizaje

Después de completar este módulo, podrá:
  • Describir los dos tipos de servicios web Apex y hacer una descripción general de alto nivel de estos servicios.
  • Crear una clase Apex REST que contenga los métodos para cada método HTTP.
  • Invocar un método Apex REST personalizado con un extremo.
  • Pasar datos a un método Apex REST personalizado mediante el envío de un cuerpo de solicitud en formato JSON.
  • Escribir un método de prueba para un método Apex REST y establecer las propiedades en una solicitud REST de prueba.
  • Escribir un método de prueba para un método Apex REST mediante la llamada al método con valores de parámetro.

Exponer la clase de Apex como un servicio web

Puede exponer los métodos de clase de Apex como una operación de servicio web REST o SOAP. Al posibilitar la llamada a los métodos basada en web, las aplicaciones externas se pueden integrar con Salesforce para realizar todo tipo de operaciones útiles.

Por ejemplo, suponga que el centro de llamadas de su compañía usa una aplicación interna para gestionar los recursos locales. Se espera que los representantes del servicio de atención al cliente usen la misma aplicación para realizar su trabajo diario, lo que incluye la gestión de registros de caso en Salesforce. Mediante una sola interfaz, los representantes pueden ver y actualizar los registros de caso y acceder a recursos internos. La aplicación llama a una clase de servicio web de Apex para gestionar los registros de caso de Salesforce.

Exponer una clase como un servicio REST

Hacer que la clase de Apex esté disponible como un servicio web REST es sencillo. Defina la clase como global y defina los métodos como globales estáticos. Agregue anotaciones a la clase y los métodos. Por ejemplo, en el caso de esta clase Apex REST se usa un solo método. El método getRecord es una llamada a la API de REST personalizada. Se anota con @HttpGet y se invoca para una solicitud GET.

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

Como puede ver, la clase se anota con @RestResource(urlMapping='/Account/*). El extremo base para Apex REST es https://suInstancia.salesforce.com/services/apexrest/. La asignación de dirección URL se anexa al extremo base para formar el extremo del servicio REST. Por ejemplo, en la clase de muestra, el extremo de REST es https://suInstancia.salesforce.com/services/apexrest/. En el caso de su organización, podría ser algo parecido a https://suInstancia.salesforce.com/services/apexrest/Account/*.

La asignación de dirección URL distingue entre mayúsculas y minúsculas, y puede contener un carácter comodín (*).

Defina cada método expuesto como global static y agregue una anotación para asociarla a un método HTTP. Las siguientes anotaciones están disponibles. Puede usar cada anotación una sola vez en cada clase de Apex.

Anotación Acción Detalles
@HttpGet Leer Se leen o recuperan registros.
@HttpPost Crear Se crean registros.
@HttpDelete Eliminar Se eliminan registros.
@HttpPut Actualizar e insertar Se suele usar para actualizar registros existentes o crear registros.
@HttpPatch Actualizar Se suele usar para actualizar campos de registros existentes.

Exponer una clase como un servicio SOAP

Hacer que una clase de Apex esté disponible como un servicio web SOAP es tan sencillo como el caso de REST. Defina la clase como global. Agregue la palabra clave webservice y el modificador de definición static a cada método que desee exponer. La palabra clave webservice proporciona acceso global al método al que se agrega.

Por ejemplo, esta es una clase de muestra con un solo método. El método getRecord es una llamada a la API de SOAP personalizada que devuelve un registro de cuenta.

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

La aplicación externa puede llamar a los métodos Apex en forma de operaciones de servicio web mediante el consumo del archivo WSDL de clase. Genere este WSDL para la clase en la página de detalles de clase, a la cual se accede desde la página Clases de Apex en Configuración. Normalmente, envía el archivo WSDL a desarrolladores externos (o lo usa personalmente) para escribir las integraciones para el servicio web.

Dado que la seguridad de la plataforma es una prioridad para Salesforce, su servicio web requiere la autenticación. Además del WSDL de clase de Apex, las aplicaciones externas deben usar el WSDL de compañía o el WSDL de socio para la funcionalidad del inicio de sesión.

Presentación de Apex REST

Ahora viene la parte divertida. Los siguientes pasos le guían durante el proceso de creación de un servicio Apex REST. En primer lugar, crea la clase de Apex que se expone como un servicio REST. A continuación, intenta llamar a varios métodos de un cliente y finalmente escribe pruebas de unidad. En este caso, es necesario escribir bastante código, pero merece la pena el esfuerzo.

La clase de Apex gestiona registros de caso. La clase contiene cinco métodos y cada método se corresponde con un método HTTP. Por ejemplo, si la aplicación cliente invoca una llamada REST para el método GET HTTP, se invoca el método getCaseById.

Dado que la clase se define con una asignación de dirección URL de /Cases/*, el extremo usado para llamar a este servicio REST es cualquier URI que empiece por https://suInstancia.salesforce.com/services/apexrest/Cases/.

Le sugerimos también la posibilidad de usar el control de versiones para los extremos de la API para poder proporcionar actualizaciones de la funcionalidad sin interrumpir el código existente. Puede crear dos clases que especifiquen las asignaciones de dirección URL de /Cases/v1/* y /Cases/v2/* para implementar esta funcionalidad.

Ahora vamos a crear una clase Apex REST.

  1. Abra Developer Console desde el icono de engranaje de Configuración (Icono de engranaje).
  2. En Developer Console, seleccione File | New | Apex Class (Archivo | Nuevo | Clase de Apex).
  3. Para el nombre de clase, ingrese CaseManager y, a continuación, haga clic en OK (Aceptar).
  4. Sustituya el código generado automáticamente por la siguiente definición de clase.
    @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. Pulse CTRL+S para guardar.

Crear un registro con un método POST

Vamos a usar la clase Apex REST que acaba de crear para pasar una rato entretenido. Primero, llamamos al método POST para crear un registro de caso.

Para invocar el servicio REST, debe usar un… ¡cliente REST! Puede usar prácticamente cualquier cliente REST, como el cliente de la API, la herramienta de línea de comandos cURL o la biblioteca curl para PHP. Usaremos la herramienta Workbench como nuestra aplicación cliente REST, pero echaremos un vistazo a cURL más adelante.

Apex REST es compatible con dos formatos para las representaciones de recursos: JSON y XML. Las representaciones JSON se pasan de forma predeterminada en el cuerpo de una solicitud o respuesta y el formato se indica mediante la propiedad Content-Type del encabezado HTTP. Dado que JSON es más fácil de leer y entender que XML, en esta unidad se usa JSON exclusivamente. En este paso, envía un registro de caso en formato JSON.

Apex REST es compatible con OAuth 2.0 y con mecanismos de autenticación de sesión. En términos sencillos, esto significa que usamos estándares de la industria para garantizar la seguridad de su aplicación y sus datos. Por suerte, puede usar Workbench para facilitar las pruebas. Workbench es un conjunto de herramientas basado en web de gran capacidad para que los administradores y desarrolladores puedan interactuar con organizaciones mediante las API de Plataforma Lightning. Con Workbench, usa la autenticación de sesión cuando inicia sesión con su nombre de usuario y contraseña en Salesforce. Además, puede usar REST Explorer para llamar al servicio REST.

  1. Navegue a https://workbench.developerforce.com/login.php.
  2. Para Environment (Entorno), seleccione Production (Producción).
  3. Seleccione la última versión de la API en la lista desplegable API Version (Versión de API).
  4. Acepte las condiciones del servicio y haga clic en Iniciar sesión con Salesforce.
  5. Para permitir que Workbench acceda a su información, haga clic en Allow (Permitir).
  6. Ingrese sus credenciales de inicio de sesión y haga clic en Log in to Salesforce (Iniciar sesión en Salesforce).
  7. Después de iniciar sesión, seleccione utilities (utilidades) | REST Explorer.
  8. Seleccione POST.
  9. La ruta de dirección URL que acepta REST Explorer está relacionada con la dirección URL de instancia de su organización. Indique solo la ruta que se anexa a la dirección URL de instancia. En el campo de entrada de URI relativo, sustituya el URI predeterminado por /services/apexrest/Cases/.
  10. Para el cuerpo de la solicitud, inserte la siguiente representación de cadena JSON del objeto que se va a insertar.
    {
      "subject" : "Bigfoot Sighting!",
      "status" : "New",
      "origin" : "Phone",
      "priority" : "Low"
    }
  11. Haga clic en Execute (Ejecutar).
    Esta invocación llama al método asociado al método POST HTTP, que en este caso es el método createCase.
  12. Para ver la respuesta devuelta, haga clic en Show Raw Response (Mostrar respuesta sin procesar).
    La respuesta devuelta es similar a esta respuesta. La respuesta contiene el Id. del nuevo registro de caso. Es probable que su valor de ID sea distinto de 50061000000t7kYAAQ. Guarde su valor de ID para usarlo en los pasos siguientes.
    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 datos con un método GET personalizado

Mediante una serie de pasos similares a los anteriores, use Workbench para invocar el método GET HTTP.

  1. En Workbench, seleccione GET.
  2. Ingrese el URI /services/apexrest/Cases/<Record ID>, lo que sustituye <Record ID> por el Id. del registro creado en el paso anterior.
  3. Haga clic en Execute (Ejecutar).

    Esta invocación llama al método asociado al método GET HTTP, que en este caso es el método getCaseById.

  4. Para ver la respuesta devuelta, haga clic en Show Raw Response (Mostrar respuesta sin procesar).

    La respuesta devuelta es similar a esta respuesta. La respuesta contiene los campos consultados por el método para el nuevo 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 datos mediante cURL

Todo buen desarrollador debe conocer como mínimo tres opciones: 1) cómo crear un GIF animado de sí mismo comiéndose un helado, 2) el valor de pi con 25 posiciones decimales y 3) cómo usar cURL. Dado que las primeras dos opciones no son relevantes para este módulo, nos centraremos en la última opción.

cURL es una herramienta de línea de comandos para obtener o enviar archivos mediante sintaxis URL. Esto es bastante útil cuando se trabaja con extremos de REST. En lugar de usar el sistema para el servicio REST de Apex, use cURL para invocar el método GET HTTP. Cada vez que usa “cURL” para el extremo de REST, pasa el Id. de sesión para la autorización. El truco cuando trabaja en Workbench es que este pasa el Id. de sesión por usted, de forma desapercibida, una vez que inicia sesión.

Para obtener un Id. de sesión, primero debe crear una aplicación conectada en su organización de Salesforce y activar OAuth. La aplicación cliente, cURL en este caso, usa la aplicación conectada para crear una conexión a Salesforce. Siga estas instrucciones para crear una aplicación conectada que proporcione la clave de consumidor y el secreto de consumidor necesarios para obtener el Id. de sesión. Al seleccionar los ámbitos de OAuth de su aplicación conectada, elija el ámbito “Acceder a sus datos y gestionarlos (api)”. El proceso de configuración de la aplicación conectada puede tardar de 5 a 10 minutos. Cuando esté listo, use el siguiente comando de cURL con sus credenciales y con la aplicación conectada.

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'

Si todo se realizó correctamente, el resultado incluirá un access_token, que corresponde a su Id. de sesión, así como una instance_url para su organización.

Respuesta de cURL con token de acceso

A continuación, ingrese su comando cURL, que será similar al que se muestra a continuación, para llamar al servicio REST de Apex y devolver la información del caso.

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

Después de pulsar Intro, verá algo similar a lo siguiente. Ahora que domina la línea de comandos, puede usar cURL, jq, sed, awk y grep siempre que lo desee. Para obtener más información sobre cURL, consulte la sección Recursos.

cURL y respuesta de la línea de comandos

Actualizar datos con un método PUT o PATCH personalizado

Puede actualizar registros con los métodos HTTP PUT o PATCH. El método PUT actualiza el recurso completo (si existe) o crea el recurso si no existe. PUT es básicamente un método de inserción y actualización. El método PATCH solo actualiza las partes especificadas de un recurso existente. En Apex, las operaciones de actualización solo actualizan los campos especificados y no sobrescriben el registro completo. Escribiremos un poco de código Apex para determinar si nuestros métodos son de actualización o de inserción y actualización.

Actualizar datos con el método PUT

El método upsertCase que ha agregado a la clase CaseManager implementa la acción PUT. Este método se incluye aquí como referencia. Este método usa el método DML integrado upsert de Apex para crear o sobrescribir campos de registros de casos al hacer coincidir el valor de ID. Si se envía un Id. en el cuerpo de la solicitud, el sObject de caso se rellena con él. En caso contrario, se crea el sObject de caso sin ningún Id. El método upsert se invoca con el sObject de caso rellenado y la declaración DML hace el resto. ¡Voilà!

@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 el método PUT:
  1. En Workbench REST Explorer, seleccione PUT.
  2. Para el URI, ingrese /services/apexrest/Cases/.
  3. El método upsertCase espera que los valores de campo se pasen al cuerpo de la solicitud. Agregue lo siguiente para el cuerpo de la solicitud y, a continuación, sustituya <Record ID> por el Id. del registro de caso que ha creado anteriormente.
    {
      "id": "<Record_ID>",
      "status" : "Working",
      "subject" : "Bigfoot Sighting!",
      "priority" : "Medium"
    }
    Nota

    Nota

    El campo de Id. es opcional. Para crear un registro de caso, omita este campo. En nuestro ejemplo, pasa este campo porque desea actualizar el registro de caso.

  4. Haga clic en Execute (Ejecutar).

    Esta solicitud invoca el método upsertCase del servicio REST. Los campos Status, Subject y Priority se actualizan. El asunto se actualiza, incluso si su valor coincide con el del asunto anterior. Además, dado que el cuerpo de la solicitud no contenía ningún valor para el campo Case Origin, el parámetro origin del método upsertCase es nulo. Por consiguiente, al actualizar el registro, el campo Origin se borra.

    Para comprobar estos campos, vea este registro en Salesforce. Para ello, navegue a https://suInstancia.salesforce.com/<Record ID>.

Actualizar datos con el método PATCH

Como alternativa al método PUT, use el método PATCH para actualizar los campos de registro. Puede implementar el método PATCH de varias formas. Una opción es especificar los parámetros en el método para cada campo que se va a actualizar. Por ejemplo, puede crear un método para actualizar la prioridad de un caso con esta firma: updateCasePriority(String priority). Para actualizar varios campos, puede incluir todos los campos que desee como parámetros.

Otra opción que permite una mayor flexibilidad consiste en pasar los campos como pares de nombre/valor JSON en el cuerpo de la solicitud. De este modo, el método puede aceptar un número arbitrario de parámetros y los parámetros no son fijos en la firma del método. Otra ventaja de esta opción es que ningún campo se borra por accidente por el hecho de ser nulo. El método updateCaseFields que ha agregado a la clase CaseManager usa esta segunda opción. Este método elimina el número de serie de la cadena JSON del cuerpo de la solicitud en una asignación de pares de nombre/valor y usa el método PUT de sObject para configurar los 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 el método PATCH:
  1. En Workbench REST Explorer, haga clic en PATCH.
  2. Para el URI, ingrese /services/apexrest/Cases/<Record ID>. Sustituya <Record ID> por el Id. del registro de caso creado anteriormente. Ingrese el siguiente JSON en el cuerpo de la solicitud.
    {
      "status" : "Escalated",
      "priority" : "High"
    }

    Este JSON incluye dos valores de campo:: status y priority. El método updateCaseFields recupera estos valores del JSON enviado, los cuales se usan para especificar los campos que se van a actualizar en el objeto.

  3. Haga clic en Execute (Ejecutar).

    Esta solicitud invoca el método updateCaseFields en el servicio REST. Los campos Status y Priority del registro de caso se actualizan a los nuevos valores. Para comprobar estos campos, vea este registro en Salesforce. Para ello, navegue a https://suInstancia.salesforce.com/<Record ID>.

Probar su clase Apex REST

Probar su clase Apex REST es similar a probar cualquier otra clase de Apex. Solo tiene que llamar a los métodos de clase mediante el paso de valores de parámetro y, a continuación, verificar los resultados. En el caso de los métodos que no aplican parámetros o que se basan en información de la solicitud REST, cree una solicitud REST de prueba.

Aquí se describe en general cómo prueba los servicios Apex REST. Para simular una solicitud REST, cree una solicitud RestRequest en el método de prueba y, a continuación, establezca las propiedades de la solicitud del modo siguiente. Además, puede agregar los parámetros que “pase” en la solicitud para simular los parámetros de 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;

Si el método que está probando accede a los valores de la solicitud mediante RestContext, asigne la solicitud a RestContext para rellenarla (RestContext.request = request;).

Ahora, vamos a guardar la clase completa en Developer Console y ejecutar los resultados.

  1. En Developer Console, seleccione File | New | Apex Class (Archivo | Nuevo | Clase de Apex).
  2. Para el nombre de clase, ingrese CaseManagerTest y, a continuación, haga clic en OK (Aceptar).
  3. Sustituya el código generado automáticamente por la siguiente definición de clase.
    @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. Pulse CTRL+S para guardar.
  5. Ejecute todas las pruebas en su organización seleccionando Test (Prueba) | Run All (Ejecutar todo).

Los resultados de las pruebas se muestran en la ficha Tests (Pruebas). Una vez finalizada la ejecución de las pruebas, compruebe la fila CaseManager en el panel Overall Code Coverage (Cobertura de código total). La cobertura es del 100 %.

Más información...

Obtenga más información sobre los tipos de datos y espacios de nombres compatibles con Apex REST, las API de Salesforce y las consideraciones en materia de seguridad.
Tipos de datos compatibles con Apex REST
Apex REST es compatible con estos tipos de datos para los parámetros y los valores devueltos.
  • Primitivos de Apex (se excluyen sObject y Blob).
  • sObjects.
  • Listas o asignaciones de primitivos de Apex o sObjects (solo se admiten asignaciones con claves de cadena).
  • Tipos definidos por el usuario que contienen variables de miembro de los tipos indicados anteriormente.
Espacios de nombres en extremos de Apex REST
Los métodos Apex REST se puede usar en paquetes gestionados y no gestionados. Al llamar a los métodos Apex REST contenidos en un paquete gestionado, debe incluir el espacio de nombres del paquete gestionado en la dirección URL de llamada REST. Por ejemplo, si la clase está contenida en un espacio de nombres de un paquete gestionado llamado packageNamespace y los métodos Apex REST usan una asignación de dirección URL de /MyMethod/*, la dirección URL usada mediante REST para llamar a estos métodos tendría el formato https://instancia.salesforce.com/services/apexrest/packageNamespace/MyMethod/.
Servicios web Apex personalizados y API de Salesforce
En lugar de usar código Apex personalizado para los servicios REST y SOAP, las aplicaciones externas se pueden integrar con Salesforce mediante el uso de API de REST y SOAP de Salesforce. Estas API le permiten crear, actualizar y eliminar registros. Sin embargo, la ventaja de usar servicios web Apex es que los métodos Apex puede encapsular lógica compleja. Esta lógica está oculta en la aplicación consumidora. Además, las operaciones con clases de Apex pueden ser más rápidas que las llamadas individuales a la API, ya que se realizan menos recorridos de ida y vuelta entre el cliente y los servidores de Salesforce. En el caso de una llamada de servicio web Apex, se envía solo una solicitud y todas las operaciones del método se realizan en el servidor.
Consideraciones sobre la seguridad de los servicios web Apex
El contexto de seguridad en el que se ejecutan los servicios web Apex difiere del contexto de seguridad de las API de Salesforce. A diferencia de las API de Salesforce, los métodos de servicio web Apex se ejecutan con privilegios del sistema y no tienen en cuenta los permisos para objetos y campos del usuario. No obstante, los métodos de servicio web Apex ejecutan reglas de colaboración cuando se declaran con la palabra clave with sharing.