En esta época en que Internet está en todas partes puede ser muy importante que nuestras aplicaciones puedan obtener datos que se encuentran disponibles para nosotros allí, en Internet, y para acceder a ellos solamente deberíamos saber como obtenerlos.
Y eso, es muy fácil de conseguir una vez que entendemos los conceptos. Veamos:
- Hay computadoras en Internet que actúan como Servidores de WebServices. O sea que el WebService nos lo provee un Servidor al cual le debemos enviar una solicitud/petición y él nos devolverá una respuesta. Es exactamente lo mismo que hacemos cuando usamos Cliente/Servidor con SQL en nuestras aplicaciones.
- Cada Servidor puede aceptar muchas solicitudes distintas y debemos decirle cual de esas distintas solicitudes es la que nos interesa. Es el equivalente a una biblioteca de funciones, hay muchas funciones en esa biblioteca ¿cuál de ellas queremos ejecutar?
- La solicitud se la enviamos al Servidor usando un formato llamado WSDL (Web Services Description Language) que está basado en XML y que se transmite por HTTP. Entonces, para entenderlo mejor: la solicitud es una URL que finaliza con las letras wsdl (bueno, no necesariamente, pero es el caso que veremos en este artículo)
- Si el estado que el Servidor nos retornó es el número 200 eso significa que está todo ok. Cualquier otro número indicará que ocurrió un error.
- Si el estado que el Servidor nos retornó es el número 200 entonces en su respuesta tendremos el dato (o los datos, porque pueden ser muchos) que habíamos solicitado.
Entonces lo que debemos hacer es:
- Crear la solicitud de ejecución de una función del WebService. A esto se le llama XML REQUEST
- Enviar el XML REQUEST al Servidor (o sea que se le envía una URL que termina con las letras wsdl)
- Esperar hasta recibir la respuesta del Servidor. A lo recibido se le llama XML RESPONSE
- Procesar esa respuesta para extraer el dato (o los datos) que necesitamos
Paso 1. Crear la solicitud de ejecución de una función del WebService
¿Cómo sabemos cuál debe ser el contenido de la solicitud? Evidentemente que cada solicitud será distinta, no es lo mismo preguntarle a un Servidor por la temperatura actual en mi ciudad que preguntarle a otro Servidor cual es la traducción de una palabra inglesa al idioma castellano.
Para responder a esa pregunta tenemos dos alternativas:
- Preguntarle al proveedor del WebService o buscar en su página web
- Usar un programa que realice esa tarea
- El autor de este blog prefiere usar un programa porque no solamente le muestra la solicitud que se debe enviar también le permite probarla y verificar su funcionamiento y recibir la respuesta. Hay varios programas que realizan esas tareas y por lo tanto cual elegir es según el gusto de cada uno. El más popular y muy completo y además gratuito se llama SoapUI y será el utilizado en estos artículos sobre WebServices.
Después de descargar e instalar al SoapUI cuando lo ejecutemos veremos algo asi:
A continuación debemos decirle de cual URL queremos obtener el formato de la solicitud que necesitamos:
En la Captura 2. puedes ver lo que debes hacer para que el SoapUI te muestre todas las solicitudes de ese WebService (o sea, todas las funciones que tienes disponibles para usarlas). La cantidad de solicitudes disponibles varía según cada Servidor, podrías tener una, dos, tres, o cualquier otra cantidad.
En la Captura 3. puedes ver lo que debes hacer para ejecutar un WebService usando al programa SoapUI. Esto es muy importante hacer porque así te asegurarás que funciona bien y que obtienes un valor correcto.
En la Captura 4. puedes ver que debes reemplazar los símbolos de ? por números, luego hacer clic en el icono de ejecutar y en instantes obtendrás la respuesta del Servidor. En este caso la ejecución fue exitosa pero si algo en la solicitud está mal (por ejemplo, pusiste letras en lugar de números) lo que obtendrás será un error y podrás saber que hay un error porque verás <soap:Fault> (bueno, no necesariamente pero es lo usual).
NOTA: No todos los Servidores envían la descripción del error en <soap:Fault> pero lo normal es que sí lo hagan.
Paso 2. Enviar el XML REQUEST al Servidor
En los paneles izquierdos de la Captura 4. y de la Captura 5. vemos las solicitudes (XML REQUEST) enviadas al Servidor y en los paneles derechos vemos las respuestas (XML RESPONSE) recibidas.
En ambos casos lo que se envía y lo que se recibe son variables de tipo string. Que desde luego podemos convertirlas a archivos de texto si lo deseamos.
Hasta ahora todo lo hicimos usando al programa SoapUI ¿y cómo podemos hacer lo mismo desde Visual FoxPro? Pues con las siguientes líneas de código:
LOCAL lcURL_WSDL, lcMiSolicitud, lcSuRespuesta, lcRespuestaWS, loHTTP
lcURL_WSDL = "la URL que me interesa"
lcMiSolicitud = "el string con formato XML que contiene mi solicitud"
lcSuRespuesta = "MiArchivo.XML" && La respuesta recibida convertida en un archivo .XML
loHTTP = CreateObject("Msxml2.ServerXMLHTTP.6.0") && conexión por HTTP
WITH loHTTP
.OPEN("POST", lcURL_WSDL, .F.)
.setRequestHeader("User-Agent", "Ejecutando un WebService")
.setRequestHeader("Content-Type", "text/xml;charset=utf-8")
*--- Se envía la solicitud al Servidor
.SEND(lcMiSolicitud)
ENDWITH
Paso 3. Esperar hasta recibir la respuesta del Servidor
En esta época las respuestas a las solicitudes de WebServices suele ser rapidísima. Para obtenerla en Visual FoxPro podemos escribir algo como:
*--- Si la propiedad Status es 200 entonces está todo ok, si es cualquier otro número entonces ocurrió algún error
IF loHTTP.STATUS = 200 THEN
lcRespuestaWS = loHTTP.responseText
*--- Se genera un archivo con formato XML de la respuesta obtenida
=StrToFile(StrConv(lcRespuestaWS, 9), lcSuRespuesta) && 9: Convierte doble-bytes caracteres a UTF-8
ENDIF
NOTA: EL Servidor nos retorna un string pero ese string está en formato XML y por lo tanto podemos guardarlo como un archivo .XML
Paso 4. Procesar esa respuesta para extraer el dato (o los datos) que necesitamos
Recuerda que el WebService nos da como respuesta un string que contiene mucho texto y solamente una pequeña parte de todo ese texto corresponde al valor que estamos necesitando, el resto es basura. Por ejemplo:
Captura 6. De todo ese string solamente queremos obtener el número 14, todo lo demás está sobrando
Entonces, ¿cómo obtenemos el número 14 y desechamos todo lo demás?
Lo más sencillo es usando una función del Visual FoxPro llamada StrExtract() que retorna el texto que se encuentra entre dos delimitadores. Entonces al escribir:
lcResultado = StrExtract(lcRespuestaWS, "<AddResult>", "</AddResult>")
en la variable lcResultado tendremos lo que buscábamos. O sea, al número 14.
IMPORTANTE: En este ejemplo los delimitadores fueron <AddResult> y </AddResult> pero en otros casos tendrás que usar otros delimitadores. ¿Cuáles delimitadores debes usar? eso lo sabrás mirando el resultado que te devuelve el Servidor de WebServices (en la Captura 4. vemos que texto está antes y después de la respuesta, o sea del número 14, y esos textos son los que debemos usar como delimitadores).
NOTA: No es la única forma de obtener la respuesta que nos envió el Servidor, también podríamos usar una función del Visual FoxPro llamada XMLTOCURSOR() para obtener esa respuesta. Cuando los datos a recibir son muchos esa puede ser la mejor alternativa.
Conclusión
Es muy fácil desde Visual FoxPro consumir WebServices (si se sabe como hacerlo, claro) y en esta época es muy importante para darle un buen valor agregado a nuestras aplicaciones. En este primer artículo de la serie sobre consumir WebServices hemos visto los conceptos generales para tener claras las ideas.
¿Y qué haríamos si queremos consumir WebServices desde Visual FoxPro?
Lo más práctico y lo más eficiente es crear una clase que se encargue de esa tarea.
En el archivo .ZIP que puedes descargar encontrarás a esa clase junto con varios programas de ejemplo. En el siguiente artículo de esta serie se explicará como funcionan la clase y los ejemplos para que todos los conceptos te queden más claros y ya te sea muy fácil consumir WebServices desde Visual FoxPro.
IMPORTANTE: En este artículo y en el siguiente se usan SOAP (Simple Object Access Protocol) y WSDL (Web Services Description Language) para consumir WebServices porque gracias al programa SoapUI es muy fácil obtener la solicitud que debemos enviar al Servidor pero ambos se están usando cada vez menos. La razón es que SOAP es tedioso para analizarlo, es difícil de leer, y ocupa mucho ancho de banda. Por eso es que ahora se prefiere usar ReST con JSON, lo cual será tema de artículos posteriores.
Descarga
Puedes descargar un archivo .ZIP que contiene a una clase para consumir WebServices y varios ejemplos de uso desde:
https://www.mediafire.com/file/i7ed505rte1fxue/WebServices.zip/file
NOTA: Todos los ejemplos funcionan perfectamente en la fecha de publicación de este artículo pero no puedo asegurar que siempre será así porque todos son gratuitos y los propietarios de los WebServices podrían darlos de baja si se les antoja. Entonces, cuanto antes los pruebes, mucho mejor.
Artículos relacionados