Añadir lógica personalizada

Objective

After completing this lesson, you will be able to implementar validaciones programáticas con la ayuda de controladores de eventos .before

Implementaciones de servicio personalizado

Como la mayoría de las tareas estándar y los casos de uso están cubiertos por proveedores de servicios genéricos, la necesidad de añadir código de implementación de servicio se reduce y minimiza en gran medida.

Los casos restantes se reducen a una lógica personalizada real, específica de su dominio y aplicación, como las validaciones programáticas específicas de dominio.

Por ejemplo, programemos una validación que asegure que la fecha de nacimiento pasada sea anterior a la fecha de muerte pasada al crear un nuevo autor a través del AdminService.

La forma más fácil de añadir implementaciones de servicio personalizadas es simplemente colocar un archivo igual de llamado .js junto al archivo .cds que contiene la definición de servicio correspondiente. Es decir, en nuestro caso colocamos un archivo llamado admin-service.js en la carpeta srv de nuestro proyecto, ya que esta carpeta también contiene el archivo admin-service.cds, que se utiliza para definir el AdminService (véase la siguiente figura).

Nota

Como alternativa, también puede anotar la definición de servicio en el archivo .cds con la anotación @impl . Esta anotación se utiliza para hacer referencia explícita a otro archivo .js que debería contener la implementación del servicio.

Existen diferentes formas de implementar la lógica personalizada necesaria en el archivo .js. La forma más común es utilizar una subclase de cds.ApplicationService para beneficiarse de implementaciones genéricas listas para usar. Esto se debe a que la clase cds.ApplicationService es la implementación por defecto del proveedor de servicios, que añade los proveedores genéricos ya discutidos a una definición de servicio.

Para crear una subclase de cds.ApplicationService, primero asignamos el módulo @sap/cds a la constante cds en nuestro código (línea 1). El módulo @sap/cds es el objeto de fachada cds que proporciona acceso a todas las API CAP Node.js.

A continuación, creamos una subclase de cds.ApplicationService en las líneas 4 a 6, en la que implementaremos nuestra lógica personalizada. El nombre de la subclase es arbitrario. Lo llamamos aquí como nuestra interfaz de servicio, es decir, AdminService.

En la línea 9, hacemos que la clase AdminService esté disponible para importarla a otros módulos. Esta es una práctica común en Node.js para estructurar el código.

Nota

Si ahora inicia la aplicación introduciendo cds watch en el terminal, el fichero de implementación de servicio añadido se visualiza en el log mediante una salida similar a la siguiente:

Code Snippet
1
[cds] - serving AdminService { path: '/admin', impl: 'srv/admin-service.js' }

Programas de control de eventos

Las implementaciones de servicio personalizadas se llevan a cabo con la ayuda de programas de control de eventos personalizados, mediante los cuales se distingue entre diferentes tipos de programas de control.

Vea el vídeo para obtener un resumen de los diferentes programas de control de eventos.

Registrando .before Event Handlers

Para la validación que queremos implementar, necesitamos un programa de control Before que se debe registrar para las operaciones CREATE y UPDATE en la entidad Authors.

Para registrar programas de control de eventos personalizados, sobrescriba el método init() heredado en la clase de implementación creada (véase la siguiente figura). No olvide llamar super.init() en la implementación para permitir que las subclases registren sus programas de control.

Para registrar un programa de control Before en el método init() , llame el método heredado before() a través de this.before(). Para ello, debe proporcionar la siguiente interfaz. Encontrará una descripción detallada de los parámetros individuales en la documentación de la PAC:

Code Snippet
12345
function before ( event : string | string[] | '*', entity? : CSN definition | CSN definition[] | string | string[] | '*', handler : function )

En el ejemplo mostrado, la función nombrada this.validateLifeData se registra para las operaciones CREATE y UPDATE en la entidad Authors. Analizaremos la implementación de esta función más adelante.

La entidad o entidades para las que debe tener lugar el registro se pueden transferir al método before() como string. Sin embargo, se recomienda pasar las definiciones de CSN aquí en su lugar. Las definiciones de CSN de las entidades que se exponen a través del servicio se ponen a disposición convenientemente a través de la propiedad this.entities .

En el ejemplo mostrado, la definición CSN necesaria para la entidad Autores se asigna a la constante Autores mediante una asignación de destrucción.

Nota

La sintaxis de asignación de desestructuración es JavaScript estándar. Es una expresión JavaScript que permite desempaquetar valores de matrices, o propiedades de objetos, en variables distintas.

Validación de datos de entrada

Por último, veamos cómo se puede implementar la función validateLifeData que se ha registrado como programa de control en la clase AdminService.

Antes de que los manejadores generalmente reciban un único argumento, una instancia de cds.Request. Esta instancia proporciona propiedades y métodos que se pueden utilizar para implementar el programa de control. En el ejemplo, hemos nombrado el argumento req (véase la siguiente figura).

Para las solicitudes CREATE y UPDATE, que nos ocupan aquí, la propiedad de datos del parámetro de interfaz contiene el cuerpo HTTP de la solicitud. Utilizamos una asignación de destrucción para asignar los valores pasados del cuerpo HTTP a las constantes dateOfBirth y dateOfDeath.

Si la fecha de fallecimiento es anterior a la fecha de nacimiento, emitimos un mensaje de error correspondiente a través del método req.error() .

Nota

El método req.error() recopila todos los fallos en la propiedad req.errors, lo que permite visualizarlos en las IU a la vez. Si hay req.errors después de la fase anterior, el procesamiento de la solicitud se cancela con una respuesta de error correspondiente devuelta al cliente.

Consejo

El literal pasado al método req.error() está delimitado con caracteres de marca (`). Estos literales de plantilla permiten que los valores de variable se incrustan en una cadena utilizando la sintaxis ${name_of_the_variable}.

Demostración y ejercicio: Proporcione un programa de control de eventos .before

Nota

Como ejercicio, lleve a cabo las instrucciones paso a paso en la siguiente demostración en SAP Business Application Studio.

Como punto de partida para el ejercicio, utilice el resultado del ejercicio anterior Definir un servicio basado en vistas desnormalizadas si lo ha completado correctamente. Como alternativa, también puede utilizar la ramificación 10_denormalized_views del siguiente repositorio de GitHub como punto de partida:

https://github.com/SAP-samples/cap-development-learning-journey

La implementación completa de la simulación se puede encontrar en la rama 11_.before_event_handler del repositorio GitHub.

Puede encontrar información detallada sobre el contenido del repositorio y cómo utilizarlo aquí.

Vea el vídeo para ver cómo proporcionar un programa de control de eventos .before.