Esta es una traducción que desde EGA Futura ofrecemos como cortesía a toda la Ohana y comunidad de programadores , consultores , administradores y arquitectos de Salesforce para toda Iberoamérica .
El enlace a la publicación original, lo encontrarás al final de este artículo.
…
La versión Spring '23 de Salesforce Platform, disponible en general a partir del 13 de febrero, agregó algunas actualizaciones fantásticas al lenguaje de Apex. Hemos implementado algunas de las actualizaciones de Spring '23 en la aplicación de ejemplo Apex-Recipes , lo que ha simplificado significativamente la base de código existente.
En esta publicación de blog, revisaremos las actualizaciones en Spring '23 para Apex con ejemplos de código. Estas actualizaciones ayudan a los desarrolladores a crear aplicaciones más seguras para sus organizaciones.
1. Operaciones de base de datos en modo usuario
Apex, de forma predeterminada, se ejecuta en modo Sistema con permisos elevados, lo que significa que los desarrolladores pueden pasar por alto los controles de seguridad sin darse cuenta al escribir código.
Antes de continuar, revisemos rápidamente los controles de seguridad que los administradores de Salesforce pueden colocar para garantizar que los usuarios solo puedan acceder y manipular los datos para los que están autorizados a ver o editar. Las viñetas a continuación resumen diferentes mecanismos para aplicar un modelo de seguridad detallado para sus datos de Salesforce.
- CRUD significa "Crear, Leer, Actualizar y Eliminar", las cuatro operaciones básicas que un usuario puede realizar en un registro en Salesforce
- FLS significa "Seguridad de nivel de campo", que determina qué campos dentro de un registro que un usuario puede ver o editar
- El uso compartido de registros permite al administrador configurar reglas sobre quién puede ver o editar un registro en función de varios criterios.
Con las operaciones de base de datos en modo usuario , los desarrolladores pueden optar por ejecutar Apex en el contexto del usuario, lo que garantiza que se apliquen las reglas CRUD/FLS y de uso compartido del usuario configuradas. Veamos esto en acción con ejemplos de código detallados.
Aplicar CRUD/FLS y reglas de uso compartido para SOQL estático
Puede indicar el modo de operación usando la palabra clave WITH USER_MODE
para el modo de usuario y WITH SYSTEM_MODE
para el modo de sistema en su consulta SOQL. Vea el ejemplo a continuación.
<dx-code-block title language code-block="List accounts = [SELECT Name, ShippingCity, ShippingStreet FROM Account WITH USER_MODE];»>
En el ejemplo anterior, al usar la palabra clave WITH USER_MODE
, la consulta respeta estas restricciones de seguridad:
- Permisos de lectura en el objeto Cuenta (configurado para Perfil/Conjunto de permisos) para el usuario
- Permisos de campo (FLS) para Nombre, Calle de envío y Ciudad de envío para el usuario
- Configuración de nivel de registro (como valores predeterminados de toda la organización y reglas de colaboración) para el objeto Cuenta para el usuario
El WITH USER_MODE
la palabra clave también es compatible con agregar SOQL para hacer cumplir CRUD/FLS y reglas de uso compartido de registros.
<dx-code-block title language code-block="List groupedResults = [SELECT SUM(AMOUNT) total FROM Opportunity WHERE AccountId = :accountId WITH USER_MODE];»>
En el ejemplo anterior, al usar la palabra clave WITH USER_MODE
, la consulta respeta estas restricciones de seguridad:
- Permisos de lectura en el objeto Oportunidad para el usuario
- Permisos de campo (FLS) para Amount y AccountId (sí, incluso los campos utilizados en la cláusula SOQL
WHERE
se verifican para FLS) para el usuario - Acceso a nivel de registro (como valores predeterminados de toda la organización y reglas de colaboración) en el objeto Oportunidad para el usuario
Para obtener más ejemplos, consulte la clase SOQLRecipes
de la aplicación apex-recipes.
Aplicar CRUD/FLS y reglas de uso compartido para SOQL dinámico
Los nuevos métodos Database
(ver documentos ) ahora admiten un parámetro AccessLevel
que le permite ejecutar operaciones de base de datos en modo de usuario en lugar de en el modo de sistema predeterminado. Veamos un código de ejemplo para ejecutar un SOQL dinámico en el modo de usuario.
<dx-code-block title language code-block="String query = 'SELECT ID, Name FROM Account LIMIT 1';
List lstAccounts = Database.query(query, AccessLevel.USER_MODE);»>
En el ejemplo anterior, el modo de usuario se aplicará de manera similar al ejemplo de SOQL estático que vimos en la sección anterior.
Para obtener más ejemplos, consulte la clase DynamicSOQLRecipes
de apex-recipes. Hemos actualizado todos los métodos de la clase para usar el parámetro AccessLevel
.
Hacer cumplir CRUD/FLS y reglas de uso compartido para SOSL
WITH USER_MODE
o WITH SYSTEM_MODE
también son compatibles con declaraciones SOSL (Lenguaje de búsqueda de objetos de Salesforce).
Veamos un ejemplo de una instrucción SOSL estática.
<dx-code-block title language code-block="String keyword = 'Alaska';
List<List> searchResults = [ FIND :keyword IN Name FIELDS RETURNING Account(Name), Contact(LastName, Account.Name) WITH USER_MODE ];»>
En el ejemplo anterior, al usar la palabra clave WITH USER_MODE
, la consulta respeta estas restricciones de seguridad:
- Permisos de lectura en los objetos Cuenta y Contacto para el usuario
- Permisos de campo (FLS) para el campo Nombre en Cuenta y campo Apellido en Contacto para el usuario
- Acceso a nivel de registro (como valores predeterminados de toda la organización y reglas de colaboración) en los objetos Cuenta y Contacto para el usuario
Para Dynamic SOSL, los nuevos métodos Search
(ver documentos ) también admiten el parámetro AccessLevel
similar a los nuevos métodos Database
. A continuación se muestra un ejemplo de cómo usar el parámetro AccessLevel
para ejecutar SOSL en el contexto de los usuarios.
<dx-code-block title language code-block="String query = 'FIND 'Edge*' IN ALL FIELDS RETURNING Account(ID,Name), Contact, Lead'; List<List> searchResults = Search.query(query, AccessLevel.USER_MODE);»>
Hacer cumplir CRUD/FLS y reglas de uso compartido para DML
Las operaciones de la base de datos pueden especificar el modo de usuario o sistema utilizando las palabras clave as user
o as system
.
El siguiente es un código de ejemplo que ejecuta DML en el modo de usuario aplicando CRUD/FLS y reglas de uso compartido.
Para Dynamic DML, los desarrolladores pueden utilizar el parámetro AccessLevel
para ejecutar operaciones de base de datos en el modo de usuario o en el modo de sistema.
Echemos un vistazo a un ejemplo de la aplicación apex-recipes para ver cómo puede diseñar métodos para que sean genéricos, de modo que el consumidor del método pueda decidir ejecutar el código en el modo de usuario o de sistema.
El fragmento de código siguiente muestra cómo invocar este método en el modo de usuario.
El siguiente fragmento de código muestra cómo invocar este método en el modo de sistema.
Para obtener más ejemplos, consulte la clase DMLRecipes
de la aplicación apex-recipes.
Consideraciones importantes
- Las operaciones de la base de datos en modo usuario generan excepciones de seguridad si se encuentra una infracción CRUD/FLS. Si tiene un requisito para evitar excepciones y aún aplicar la seguridad, use el método
Security.stripInaccessible()
(consulte los documentos ). Consulte la claseStripInaccessibleRecipes
(ver documentos ) de la aplicación apex-recipes para ver ejemplos de código. - Si usa la palabra clave
WITH SECURITY_ENFORCED
en sus declaraciones SOQL para hacer cumplir CRUD/FLS, ahora le recomendamos que use la palabra claveWITH USER_MODE
en su lugar debido a las siguientes razones:- La consulta SOQL que usa la palabra clave
WITH USER_MODE
admite muchas innovaciones nuevas, como reglas de restricción, reglas de alcance y cualquier otra operación de seguridad para el acceso a datos y CRUD/FLS, que la plataforma puede agregar en el futuro, por lo que es una especie de prueba del futuro - La consulta SOQL que usa la palabra clave
WITH USER_MODE
maneja casos de uso de seguridad complejos mucho mejor. Por ejemplo,WITH USER_MODE
es compatible con SOSL y consultas polimórficas . - Las declaraciones SOQL que usan la palabra clave
WITH USER_MODE
manejan CRUD/FLS para los campos usados en la cláusulawhere
yorder by
o campos usados en la consulta de relación o búsqueda polimórfica - Las consultas SOQL que utilizan la palabra clave
WITH USER_MODE
funcionan mucho mejor en comparación con el usoWITH SECURITY_ENFORCED
- La consulta SOQL que usa la palabra clave
- El modo de usuario anula la configuración de nivel de clase para la consulta SOQL o DML escrita en modo de usuario. Exploremos esto con el siguiente código de ejemplo.
<dx-code-block title language code-block="public without sharing ExampleCls { public static List getAccount() { String query = ‘SELECT Id FROM Account Limit 1’; return Database.query(query, AccessLevel.USER_MODE); } }»>
En el ejemplo anterior, aunque la clase Apex está configurada para ejecutarse en el contexto del sistema (sin la palabra clave compartida), la consulta SOQL se ejecuta en el modo de usuario, lo que refuerza la seguridad. El modo de usuario para la operación (SOQL/SOSL o DML) anula el uso compartido a nivel de clase.
2. Pasar dinámicamente variables de vinculación a consultas SOQL
Spring '23 agregó nuevos métodos como Database.queryWithBinds
, Database.getQueryLocatorWithBinds
y Database.countQueryWithBinds
.
Estos métodos proporcionan los siguientes beneficios:
- Anteriormente, si los desarrolladores usaban variables de vinculación en SOQL dinámico (usando el método
Database.query
) que están fuera de contexto, la consulta no podía resolver las variables. ConqueryWithBinds
, las variables de vinculación de la consulta se resuelven directamente desde un parámetroMap
con una clave en lugar de variables de código de Apex. - Con
Database.queryWithBinds
, los ataques de inyección SOQL se evitan automáticamente.
Echemos un vistazo a un ejemplo de código para comprender el segundo punto con más profundidad.
<dx-code-block title language code-block="public static List simpleBindingSoqlQuery(Map bindParams) { String query = ‘SELECT Id, Name ‘ + ‘FROM Account ‘ + ‘WHERE name = :name’; return Database.queryWithBinds( query, bindParams, AccessLevel.USER_MODE );
}»>
El código anterior ejecuta un SOQL dinámico en el modo de usuario. El método acepta un parámetro Map
y se puede llamar usando el código a continuación.
<dx-code-block title language code-block="String accountName = 'Codey And Co';
Map nameBind = new Map{‘name’ => accountName};
List accounts = simpleBindingSoqlQuery(nameBind);
System.debug(accounts);»>
Tenga en cuenta que no es necesario que nos aseguremos de que el nombre de la variable esté en el mismo ámbito de método que la consulta dinámica. Además, no es necesario usar el método String.escapeSingleQuotes
para el valor en la variable name
cuando se usa queryWithBinds
.
Para obtener más ejemplos de código, consulte esta solicitud de incorporación de cambios en nuestro repositorio de GitHub apex-recipes.
3. Especifique un retraso en la programación de trabajos en cola
Otra característica importante que lanzamos en Spring '23 es la capacidad de especificar demoras para trabajos programados que se pueden poner en cola.
Puede ser beneficioso ajustar el tiempo antes de que se ejecute el trabajo en cola en los siguientes casos de uso:
- Si el sistema externo tiene una velocidad limitada y puede sobrecargarse con trabajos en cola encadenados que realizan llamadas rápidas
- Al sondear los resultados, y ejecutar demasiado rápido puede provocar el uso desperdiciado de los límites diarios de Apex asíncrono
Usa el método System.enqueue(queueable, delay)
(ver docs ) para especificar retrasos. Los retrasos pueden variar de cero a 10 minutos. Veamos un ejemplo para comprender mejor esta función.
El ejemplo anterior agrega un trabajo para la ejecución asincrónica retrasada al pasar una instancia de la implementación de su clase de la interfaz Queueable
para la ejecución. Hay un retraso mínimo de cinco minutos antes de que se ejecute el trabajo.
Especificar un retraso predeterminado en toda la organización en la programación de trabajos en cola
Actualmente, si tiene un trabajo en cola de Apex, utiliza el tiempo estándar en cola sin demoras adicionales. Los administradores pueden definir un retraso predeterminado en toda la organización para todos los trabajos en cola que no especifican retraso usando
System.enqueue(queueable, delay)
. Este es principalmente un mecanismo para manejar trabajos fuera de control que podrían estar ejecutándose demasiado rápido.
Importante consideración
Cuando establece el retraso en 0 (cero), el trabajo en cola se ejecuta lo más rápido posible. Con trabajos en cola encadenados, implemente un mecanismo para ralentizar o detener el trabajo si es necesario. Sin un mecanismo a prueba de fallas de este tipo, puede alcanzar rápidamente el límite de Apex asíncrono diario.
También hay una próxima función Beta en la versión Summer '23 (planificada para estar disponible el 10 de junio de 2023 en todas las organizaciones) que permite a los desarrolladores controlar la profundidad de los trabajos en cola encadenados.
4. Obtenga el SObject
de origen de una instancia DescribeFieldResult
usando el nuevo método getSObjectType
El método getSObjectType
(ver documentos ) en el objeto DescribeFieldResult
(ver documentos ) es un método de mejora de la calidad de vida del desarrollador que se implementó en Spring '23.
Anteriormente, los desarrolladores tenían que hackear y escribir código adicional para obtener el objeto de origen de la información del esquema de campos obtenida a través de la descripción del campo. Puede consultar las soluciones anteriores a través de esta publicación de stackexchange .
A continuación se muestra un ejemplo de código de cómo usar el nuevo método getSObjectType
.
Con el método getSObjectType
, los desarrolladores ya no tienen que pasar el nombre del objeto como una cadena. Consulte un ejemplo más completo en las notas de la versión de Spring '23.
Actualizaciones de herramientas
Hemos actualizado el servidor de idioma de Apex para admitir las últimas adiciones de sintaxis, como insert as user,
insert as system
y mucho más. Y ahora admitimos las últimas adiciones de sintaxis en el lanzamiento reciente de las Extensiones de Salesforce para VSCode .
También quiero agradecer a Dang Mai por actualizar el complemento más bonito para Apex (usado para formatear el código Apex automáticamente) para admitir todas las palabras clave introducidas para las operaciones de la base de datos en modo usuario.
Conclusión
En conclusión, la versión Spring '23 de Salesforce incluye varias actualizaciones. Mediante el uso de estas nuevas funciones, los desarrolladores pueden crear aplicaciones más eficaces y seguras para sus organizaciones.
Los equipos de productos de Apex no se detienen ahí y hay más innovaciones en la hoja de ruta. Puede obtener una vista previa de lo que viene para Apex en Summer '23 (nuestro próximo lanzamiento) en la vista previa de las notas de la versión . También recomiendo ver la grabación de la sesión TrailblazerDX '23, Apex: What's New and What's Coming , para aprender más sobre lo que se está cocinando.
Referencias adicionales
Sobre el Autor
Mohith Shrivastava es promotor de desarrollo en Salesforce con una década de experiencia en la creación de productos a escala empresarial en la plataforma de Salesforce. Actualmente se está enfocando en las herramientas para desarrolladores de Salesforce, Flow, Apex y Lightning Web Components en Salesforce. Mohith se encuentra actualmente entre los principales contribuyentes en Salesforce Stack Exchange, un foro de desarrolladores donde los desarrolladores de Salesforce pueden hacer preguntas y compartir conocimientos. Puedes seguirlo a través de su Twitter @msrivastav13 .
Obtenga las últimas publicaciones de blog de desarrolladores de Salesforce y episodios de podcast a través de Slack o RSS.
Agregar a Slack Suscríbete a RSS
…
Esta es una traducción realizada por EGA Futura, y este es el link a la publicación original: https://developer.salesforce.com/blogs/2023/05/write-simplified-and-secure-apex-with-spring-23-updates.html