Blog ID-INFO

Servicios web en IBM i

Probablemente haya oído hablar de los servicios web, pero ¿qué son exactamente?

Si consulta su buscador favorito, aprenderá que un servicio web es un protocolo de interfaz que permite a dos aplicaciones hablar entre sí. Se basan en tecnologías web para permitir que dos aplicaciones, que pueden ser completamente distintas, intercambien información.

Por ello, los servicios web se utilizan a menudo en entornos distribuidos donde muchas aplicaciones heterogéneas necesitan comunicarse entre sí. Además, estas herramientas se hacen eco de los principios de la arquitectura orientada a servicios (SOA), cada vez más presentes en nuestros sistemas de información y que nos permiten ser mucho más flexibles en cuanto a las soluciones que podemos aportar.

Los servicios web actuales se basan en el Protocolo de Transferencia de Hipertexto (HTPP) para transmitir información. El uso de esta norma tiene la enorme ventaja de evitar un gran número de problemas de conectividad entre nuestras dos aplicaciones.

Los servicios web se basan en intercambios cliente/servidor. En la práctica, la aplicación que proporciona el servicio (a menudo denominada «exponer el servicio») está a la escucha de las solicitudes de los clientes. El servidor interpreta la solicitud, la procesa y envía la respuesta a la aplicación cliente de forma que ésta pueda entenderla.

 

Existen dos familias principales de servicios web:

  • Servicios web SOAP: Protocolo simple de acceso a objetos
  • Servicios web REST: transferencia de estado representacional

 

Los primeros se basan en el protocolo del mismo nombre. Existe desde hace mucho tiempo: la versión inicial definida por Microsoft e iBM data de hace 23 años, y luego se convirtió en estándar a raíz de una recomendación del W3C. El protocolo se basa totalmente en el lenguaje XML para describir formalmente los intercambios entre los clientes y el servidor. Este formalismo (a través de documentos XML llamados WSDL) tiene la ventaja de proporcionar documentación implícita cuando se utiliza este tipo de servicio. Por desgracia, esta familia adolece de algunos inconvenientes: el lenguaje XML es especialmente prolijo, por lo que utilizar este tipo de servicio web puede complicarse rápidamente. Por otro lado, el formalismo implica que los clientes y el servidor están fuertemente acoplados, lo cual, en un enfoque SOA en el que siempre buscamos una mayor flexibilidad, no es necesariamente deseable.

 

Estos inconvenientes propiciaron la aparición de la familia REST de servicios web. Se basan en los conceptos arquitectónicos utilizados en la web para manipular recursos remotos en forma de texto. A diferencia de los servicios web SOAP, la familia de servicios web REST no se limita al formato XML para intercambiar información entre aplicaciones cliente/servidor: ahora se utilizan habitualmente formatos como JSON. Para manipular recursos remotos, estos servicios web utilizan métodos http : POST, GET, PUT, DELETE, … que se hacen eco del modelo de desarrollo CRUD, lo que explica que estos servicios web se utilicen frecuentemente para construir API (Application Programming Interface) completas para interactuar con los elementos de una aplicación.

 

Pero, ¿qué pasa con nuestro IBM i? ¿Puede encajar también en estos entornos distribuidos?

 

Permítame tranquilizarle de entrada: nuestra plataforma favorita dispone de una enorme variedad de herramientas para exponer o consumir servicios web. Como muchas otras plataformas, podemos implantar estos servicios de diversas formas y ponerlos a disposición de nuestros distintos clientes.

 

Para ilustrar nuestro punto de vista, tomemos una aplicación existente desarrollada en RPGIV.

 

Para ello, vamos a empezar por crear un entorno con algunas tablas y datos. Afortunadamente para nosotros, IBM nos ha proporcionado un procedimiento almacenado SQL de una sola línea para este fin:

LLAMAR A QSYS.CREATE_SQL_SAMPLE(‘RHDB’);

 

Así que abramos nuestra herramienta de ejecución de scripts SQL en ACS y empecemos.

 

Como habrás adivinado por el nombre de la colección que hemos creado, vamos a trabajar con datos de recursos humanos.

 

Un vistazo rápido en el explorador de bases de datos nos muestra las tablas que se han creado.

 

Veamos la tabla EMPLEADO y escribamos un pequeño programa para recuperar información sobre un empleado.

 

Supongamos que tenemos un programa de servicio que extrae información sobre un empleado.

      /if not defined(IMPORT_PROTOTYPES)         ctl-opt option ( *nodebugio : *srcstmt )           debug           nomain           pgminfo(*PCML : *MODULE);       * Parametres SQL.         exec sql           set option commit = *none,                      closqlcsr = *endmod;

      *======================================================================= *       *                                                                        *       * ATTENTION :                                                            *       *                                                                        *       * ---------------------------------------------------------------------- *       * FONCTION     : Module RH.                                              *       * DESCRIPTION  : Manipulation donénes du personnel.                      *       *                                                                        *       * Creation ... : 25/10/2021   par  L. KIEFFER (Notos-Id Info)            *       * ---------------------------------------------------------------------- *       * Modification :                                                         *       * JJ/MM/AAAA - XXXXXX XXXXXXX - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.     *       *                                                                        *
      * ---------------------------------------------------------------------- *       /endif       *----------------------------------------------------------------------       * Prototype verification sous systeme.       * ---------------------------------------------------------------------         // Information employé.         dcl-ds MODULERH_employe template qualified;            prenom varchar(12);            nom varchar(15);            service varchar(36);         end-ds;         // Recherche d'un employé.         dcl-pr MODULERH_rchEmp;           iNumEmp char( 6 ) const;           oInfEmp likeds ( MODULERH_employe );           oErrHTTP int(5);           oErrMsg varchar(40);         end-pr;       * Fin des elements exportes.       /if defined(IMPORT_PROTOTYPES)       /eof       /endif       *----------------------------------------------------------------------       * Declarations globales       * ---------------------------------------------------------------------       // ---------------------------------------------------------------------       // Recherche d'employé.       // ---------------------------------------------------------------------         dcl-proc MODULERH_rchEmp export;           dcl-pi *n;             iNumEmp char( 6 ) const;             oInfEmp likeds ( MODULERH_employe );             oErrHTTP int(5);             oErrMsg varchar(40);           end-pi;           // Recherche de l'employé.           exec sql             Select FIRSTNME, LASTNAME, DEPTNAME             into :oInfEmp.prenom, :oInfEmp.nom, :oInfEmp.service             From EMPLOYEE             Join DEPARTMENT on DEPTNO = WORKDEPT             Where EMPNO = :iNumEmp;           if sqlCode < 0;             oErrHTTP = 500;             oErrMsg = 'Erreur recherche de l''employé.';             return;           endif;           if sqlCode = 100;             oErrHTTP = 404;             oErrMsg = 'Employé inconnu.';             return;           endif;           // Tout s'est bien passé.           oErrHTTP = 200;           oErrMsg = *blanks;           return;         end-proc;

 

Fíjate en las instrucciones resaltadas, a las que volveremos más adelante cuando expliquemos nuestro servicio web.

 

Para continuar, necesitaremos un servidor de servicios web en el que se alojarán nuestros servicios. Afortunadamente para nosotros, IBM proporciona uno en IBM i: IWS (Integrated Web Services server).

Para acceder a ella, utilice la siguiente URL: http: //mon_ibm_i:2001/HTTPAdmin

Donde mi_ibm_i es la dirección IP de su partición o su nombre DNS.

 

ADVERTENCIA : Si la página no se muestra, probablemente se deba a que la aplicación de administración web no se ha iniciado correctamente.

Ejecute el siguiente comando en una línea de comandos 5250:

 

STRTCPSVR SERVIDOR(*HTTP) HTTPSVR(*ADMIN)

 

Identifíquese utilizando un perfil con derechos *IOSYSCFG.

En la nueva página que aparece, haga clic en el enlace «Crear servidor de servicios web» y déjese guiar por el asistente.

 

Ponga a su servidor el nombre que desee. Por defecto, se creará una instancia de Apache.

 

Seleccione los puertos utilizados por el servidor.

 

Puedes personalizar el trabajo del servidor proporcionándole un jobd específico.

 

También puede elegir el perfil de usuario utilizado por el trabajo de servidor. Recuerde definirlo claramente. Una buena idea es establecer este perfil en el perfil de propietario de la base de datos que va a manipular. Tenga en cuenta que si elige el usuario por defecto QWSERVICE, deberá asignarle una contraseña.

 

Por último, confirme la creación del servidor pulsando el botón «Finalizar».

 

Ahora que tenemos un servidor, hablemos de nuestro primer servicio. Para ello, seleccione el servidor que ha creado anteriormente y haga clic en el enlace «Gestionar servicio desplegado».

Haga clic en el botón «Gestionar servicio desplegado». A continuación, haga clic en el botón «Desplegar».

 

La primera página del asistente le permite seleccionar el ejecutable que implementa su servicio. Desde V7.3, también puede utilizar el lenguaje sql para implementar el servicio.

Para las implementaciones RPG IV, sólo se pueden seleccionar componentes ejecutables (programas y programas de servicio). En nuestro caso, elijamos nuestro programa de servicio MODULERH.

 

La siguiente pantalla nos permitirá elegir un nombre de recurso. En nuestro caso, lo llamaremos «employes» porque estamos manipulando datos de empleados.

 

La siguiente página nos permite restringir el acceso al servicio web a un puerto seguro (vía SSL). Como no hemos asegurado nuestro servidor http, respondemos «No».

También podemos solicitar autenticación para este servicio web.

En este caso, sólo está disponible la autenticación «básica». En este caso, el cliente deberá proporcionar un usuario y una contraseña válidos en el sistema en la cabecera http «Autorización».

 

El siguiente paso en el caso de programas de servicio le permitirá seleccionar el procedimiento exportado que implementa el servicio (en este caso modulerh_rchemp).

 

A continuación, el asistente le preguntará cómo notificar al cliente que el servicio se ha realizado según lo previsto o con algún error. Aquí puede cambiar los códigos de retorno y los mensajes de error predeterminados.

 

La página siguiente es la más importante. Describe cómo accederán los clientes a su servicio.

Podemos definir :

  • El verbo http utilizado (en este caso GET)
  • El modelo de url utilizado para el acceso

Esto nos permite definir dónde se colocan nuestros parámetros cuando se suministran directamente en la URL. La sintaxis a utilizar es: /{nom_parametre}

Tenga en cuenta que también puede añadir una expresión regular a la sintaxis para comprobar la validez del parámetro introducido (aquí \d+ para una cadena numérica de al menos un dígito).

  • Una variable de salida utilizada para devolver el código http (debe definirse como un entero en el RPG que implementa el servicio).
  • Variable de salida alfanumérica que sustituye al mensaje de error por defecto.
  • Los tipos de datos aceptados como entrada (*Todos corresponden a todos los tipos gestionados: xml, json, datos de formulario, etc. => en este caso, el cliente debe especificar qué tipo de información está proporcionando para que el servidor la entienda).
  • Tipos de datos devueltos: la herramienta puede devolver datos en formato xml o json. Una vez más, si el servidor puede proporcionar ambos, el cliente tendrá que especificar cuál prefiere.
  • Cómo se presentan los datos de entrada y salida: encapsulados o por nombre.

Por último, esta pantalla permite indicar de dónde se recuperarán los parámetros de entrada. En nuestro caso la url utilizando el identificador num (recuerda que es el definido en la plantilla url).

 

La siguiente pantalla le permitirá definir un usuario específico para ejecutar este servicio web. El perfil de servidor general debe tener acceso a este perfil de servicio web específico.

 

La siguiente pantalla se utiliza para definir las bibliotecas que se añadirán al entorno de ejecución.

 

La penúltima pantalla permite configurar los elementos que se pasarán al programa que implementa el servicio.

 

La última pantalla resume la información introducida. Haga clic en el botón «Finalizar» para desplegar e iniciar el servicio web.

 

Pero, ¿cómo probar nuestro famoso servicio web?

Como el servicio web utiliza el verbo GET, un simple navegador nos permitirá probarlo.

 

Para casos más complejos, puede recurrir a herramientas más completas como :

  • CURL (si no te importan las líneas de comandos): te permite configurar completamente tu petición (autenticación, cabeceras http, etc.).
  • PostMan: herramienta gráfica tan completa como CURL.

 

Un ejemplo rápido usando PostMan: añadimos una cabecera http indicando que sólo queremos JSON para la respuesta (recuerda que nuestro servicio web puede proporcionar xml o json).

 

Y eso es todo, la ‘R’ de nuestra API CRUD está ahora en su lugar, todo lo que queda es crear los otros procedimientos que implementan las funciones que faltan. No olvides la importancia de los verbos http a la hora de configurar todo esto:

C => POST

R => LEER

U => PUT

Y D => DELETE.

 

Espero que este post haya aclarado un poco el tema. Esperamos verle la próxima vez, cuando podamos ponernos en la piel del cliente y no en la del servidor.

 

¿Tiene alguna pregunta sobre los servicios web o su plataforma IBM i? Póngase en contacto con nosotros en el 01 88 32 12 34 o a través del formulario de contacto.

Partager cet article