miércoles, 3 de mayo de 2017

SAP UI5 y oData: Asociaciones, navegación y expand (I, teoría)

Cuando tenemos una tabla sencilla en SAP y queremos mostrar los datos en una aplicación SAP UI5, nos podemos crear una aplicación que consuma un servicio oData sencillito y nos quedamos tan contentos (como podemos hacer viendo los distintos post en la página de tutoriales).

Pero claro, las cosas no son tan sencillas, y seguro que nos toca crear una aplicación que muestre datos de muchas tablas que están relacionadas entre ellas. Manda narices, siempre pidiéndonos cosas complicadas.

Pues para solucionar ese problema, vamos a aprender tres cosas muy importantes en un servicio oData: las asociaciones, las navegaciones y el expand.

Gracias a las asociaciones (y compañía), podremos crearnos una aplicación en SAP UI5 que nos muestre los datos de ambas tablas relacionadas, sin tener que comernos mucho la cabeza para hacer múltiples llamadas al servicio oData y tratar los datos en la aplicación. Con una llamada obtendremos los datos de ambas tablas, de sopetón.



Qué es una asociación, una navegación y el expand


Básicamente, las asociaciones nos dicen como se relacionan dos tipos de entidad, una navegación es una propiedad de un tipo de entidad para navegar a otro tipo de entidad (usando una asociación) y el expand es una cláusula que se usa al llamar al servicio oData para invocar una navegación. Muy básicamente. En la página de oData podemos obtener la documentación oficial... pero en inglés y sin ejemplos, así que cualquiera se entera al leerlo por primera vez.

Explicando con un ejemplo


Mejor vamos s a explicarlo con un ejemplo para entenderlo de verdad. Lo haremos en tres pasos:

  • En este post explicaremos la teoría, pero explicándolo con un ejemplo.
  • En el siguiente post veremos como crear las asociaciones y navegaciones y editar el ABAP para proporcionar la información.
  • Por último, veremos cómo usar el expand en una aplicación SAP UI5 para aprovechar la asociación que habremos creado.

El ejemplo implica crear la típica aplicación que nos pueden pedir en cualquier empresa que se digne: Ver todos los personajes de las distintas sagas de ciencia ficción, específicamente de Space Opera.

Aplicación típica que me piden en todas partes. Tengo que patentarla.

Esta información la obtenemos de dos tablas en SAP, del famoso componente "SAP for freakies" (S4F). Una primera tabla guarda las sagas de películas (Star Wars, Star Trek, etc.) y otra, los personajes (Luke Skywalker, James Tiberius Kirk, Comandante Adama, Malcom Reynolds y más).
Unas tablas curradísimas

De lo que partimos


Previamente habremos creado un servicio oData con dos tipos de entidad: Saga y Personaje (y las colecciones correspondientes). Nada nuevo que no hayamos contado ya. Ojo, dos tipos de entidad, pero un único servicio oData.

El cambio con post anteriores, es que en esta aplicación vamos a mostrar información de los dos tipos de entidad, tanto de la saga (el nombre y cualquier otro dato que queramos añadir) como de los personajes, todo ello en la misma pantalla.

Gracias a las asociaciones, podremos obtener, con una única llamada, toda la información de ambos tipos de entidad.

La asociación


Lo primero que haremos será crear una asociación, que nos indicará cómo se relacionan los dos tipos de entidad.

Con una asociación enlazaremos el tipo de entidad Saga con el Personaje

La navegación


Lo siguiente es crear la navegación, que toma como referencia la asociación creada. Es decir, la asociación dice cómo se relacionan, y la navegación cómo se usan... por explicarlo de alguna manera.

Podemos crear una única navegación (por ejemplo, sólo de Saga para obtener sus Personajes pero no al revés, porque no nos interese) o dos navegaciones (de Saga hacia Personaje y de Personaje hacia Saga). Lo que estaremos diciendo con la navegación es algo como "cuando consulto una saga, puedo obtener sus personajes mediante la navegación LosPersonajes".

Si obtenemos los datos de una saga, gracias a la navegación LosPersonajes podremos obtener los datos de los personajes de esa saga

Lógicamente, esto no es directo, luego mediante ABAP (en la data provider class) tendremos que programar el código para obtener la información.


Consumir el servicio y usar el expand


Hecho esto (y programado todo), podremos obtener los personajes de una saga con una única llamada. Lo podremos hacer de dos formas:

  • /sap/opu/odata/sap/ZSAGAS_SRV/Sagas('STARWARS')/LosPersonajes
  • /sap/opu/odata/sap/ZSAGAS_SRV/Sagas('STARWARS')?$expand=LosPersonajes
La primera nos dará los datos de los personajes de la saga Star Wars, pero no los datos de la saga. Es como si le pidiésemos "dime los personajes de Star Wars... pero no me sueltes rollos de Star Wars, sólo quiero los personajes".

La segunda, que usa el expand, nos dará los datos de la entidad Star Wars y una propiedad adicional, que es la navegación LosPersonajes, donde tenemos todos los personajes. Estamos diciendo "dame los datos de Star Wars y sus personajes". Es decir, con una única llamada, tendré toda esa información. Esta segunda es la que, en general, nos puede resultar más interesante (aunque no tiene por que ser siempre, claro).

Una única llamada y tengo los datos de una saga y su colección de personajes


Esta información, por supuesto, la podemos encontrar en el documento metadata del servicio


Atención: Hay que estar atento con el nombre de la navegación, ya que hay que indicar el nombre de la navegación, no el nombre de la entidad a la que navegas. Es decir:
  • Saga('STARWARS')?$expand=Personajes => MAL
  • Saga('STARWARS')?$expand=LosPersonajes => BIEN

¿Por qué digo esto, que puede parecer evidante? Porque al principio nos podemos confundir, pensando que lo que indicamos es el nombre del entityset, así que no está de más mencionarlo. Si resulta que veis un ejemplo en el que se usa el nombre del entityset... es porque a lo mejor la navegación se llama igual ;).

Con esto, ya hemos explicado la parte teórica con un ejemplo. Un poco más largo que en la explicación básico del principio, ¿verdad?

¿Y ahora qué?


En los siguientes post veremos cómo programar el servicio oData en ABAP y cómo hacer la aplicación SAP UI5 para usar el expand. Pero podéis ver ejemplos reales de como funciona con el servicio de ejemplo de Northwind:





4 comentarios:

  1. Hola, muy buen aporte, sigan así ! Tengo un servicio OData que lo importo de una RFC y al momento de hacer una prueba desde la /n/IWFND/MAINT_SERVICE a mi servicio, me arroja un estatus de OK, pero no trae ningún resultado en las propiedades. Mando algo como esto ZBOLTESTDR_SRV/BolSet(PiCustomerId='1000053',PiBolNumber='TESTBOL2').

    Tienen alguna idea de que es lo que está sucediendo?

    ResponderEliminar
    Respuestas
    1. A bote pronto no se me ocurre, ¿si ejecutas la rfc de forma independiente te devuelve valores? ¿Lo mismo hay un problema de autorizaciones y no devuelve nada, o para esa entidad no hay nada que devolver? ¿Has probado a debuggear para ver que devuelve el método abap?

      Eliminar
  2. Hola una pregunta por si ud Sr Calleja o alguien mas me pueda echar una mano tengo un boton que me llama un odata y me devuelve la data, todo bien hasta aca el problema es que trato y he tratado leyendo aca https://help.sap.com/saphelp_uiaddon10/helpdata/en/91/f05e8b6f4d1014b6dd926db0e91070/frameset.htm y aca https://help.sap.com/saphelp_uiaddon10/helpdata/en/91/f0f3cd6f4d1014b6dd926db0e91070/frameset.htm y la documentacion pero o no he entendido bien o no se que pasa pero esa data que me devuelve es una sola linea y no he podido imprimir en un text box dejo aca mi pregunta en stackoverflow a ver si me pueden hechar una mano :

    https://stackoverflow.com/questions/49308445/binding-text-sap-ui5-shows-empty?noredirect=1#comment85644462_49308445

    ResponderEliminar
    Respuestas
    1. Hola Naoto,perdona la tardanza pero no recuerdo haber recibido aviso de este comentario :(

      No he podido acceder a tu post en stackoverflow, ¿te respondieron o diste con la solución? Sin ver el código no sabría decirte

      Eliminar