Como acceder a múltiples servicios web en paralelo con PHP

Octubre 11, 2009 by Demián Rodríguez 3 Comments »

Veamos el caso de una aplicación Web donde se realizan búsquedas en base a cierta información ingresada por el usuario, y para generar los resultados, el sistema debe consultar varios servicios web, los cuales tardan varios segundos en responder. Habría que buscar una forma de minimizar el tiempo de búsqueda para que al cliente le lleguen los resultados antes que la muerte.
La solución que propongo fue aplicada en un sistema de búsqueda y reserva de vuelos y hoteles.

Se pueden utilizar varias técnicas, yo tuve en cuenta las siguientes:

  • Acceder a los web services en forma concurrente utilizando CURL: Se podría buscar y generar la página de resultados directamente, o hacerlo mediante AJAX, lo cual nos permitiría hacer un polling e ir obteniendo resultados parciales.
    Sería la solución mas elegante, pero hay que tener en cuenta que desgraciadamente no todos los web services son de tipo REST y algunos usan SOAP, por lo tanto se hace dificil implementarlo usando esta librería porque habría que generar el XML e interpretar la respuesta manualmente. Mucho trabajo a mi parecer.
  • Implementar threads: Quizás piensen en el suicidio antes de tener en cuenta esta opción.
  • Buscar la solución en el lado del cliente y enviar una petición AJAX por cada web service: Aún así tenemos el problema de los límites de conección por host que imponen algunos navegadores como IE 6 y 7.

En principio opté por la última opción, pero me vi forzado a descartar el uso de AJAX debido a que algunos browsers imponen un límite de 2 conecciones concurrentes por host y yo necesito consultar 6 servicios web. Para evitar este límite tenemos que engañar al navegador creando al menos 3 subdominios, los cuales nos permitiría realizar 6 peticiones en paralelo, 2 por cada uno.
Quizás la solución no es muy elegante pero es muy usada para agilizar la descarga de los distintos componentes de la página. Tal es el caso de Google Maps, que utiliza subdominios mt0.google.com, mt1.google.com, mt2.google.com, etc.
Si bien no podemos enviar una petición a otro subdominio usando AJAX (hasta el momento), podemos inyectar un script en el documento y cumpliría la misma función, siempre y cuando la respuesta sea en formato JSON. Aca va un ejemplo usando jQuery:

$(function() {
    var webServices = [1,2,3,4,5,6]; // id's de los webservices
    var count = 1, host;
    for (var i = 0; i < webServices.length; i++) {
        // generamos un host
        host = 'http://ws' + count + '.' + location.host + '/search?ws=' + i;
        if ((i+1)%2 == 0) count++;
        // enviamos el request, jQuery inyecta el script en el documento al detectar otro dominio
        $.getJSON(host, function(json) {
            // actualizamos los resultados...
            $('#results').html(json.results);
        });
    }
});

Aunque en el título menciono a PHP, mas bien nos limita en vez de darnos una solución práctica.

  • Share/Bookmark
 

3 Responses to “Como acceder a múltiples servicios web en paralelo con PHP”

  1. Si alguien tiene otras opciones o piensa que con PHP se puede hacer facilmente, me gustaría saber!

  2. El Barto dice:

    Y si no ibas a explicar cómo usar PHP para qué lo mencionaste en el título? Yo pensé que habías hecho un cliente “multi-thread” usando cURL en PHP.

    En cuanto a lo que decís de que los webservices usan SOAP en vez de REST, un comentario al margen… el problema de SOAP me parece que es en el overhead (en transferencia y en procesamiento para generar el DOM de un mensaje soap). Pero justamente al ser un protocolo mucho más estructurado que REST, se podría codear un cliente SOAP en Javascript que genere y decodifique mensajes SOAP, con lo cual sería mucho más fácil implementar clientes de distintos webservices SOAP que REST. Lo que pasa que eso no se justificaría nunca por el overhead espantoso de SOAP y WSDL.

  3. No entiendo porque haría un cliente SOAP en Javascript que interprete un xml gigante cuando tengo la posibilidad de hacer un simple request a un web service REST que me devuelve los datos en JSON listos para usar sin ningun procesamiento extra. Tal es el caso del servicio de geocodificación de Google Maps, la API de Flickr, etc

Leave a Reply