Cómo consumir un WebService REST con PHP

Un poco de background como para asegurarnos de que hablamos de lo mismo

Qué es un webservice

Un webservice (o servicio web) es una forma de integrar aplicaciones web. Básicamente se trata de un servidor que expone parte de su funcionalidad para que sus clientes (que generalmente son otros servidores de diferentes aplicaciones) puedan utilizarlas.

Las principales ventajas de usar web services son:

  1. La posibilidad de valernos de la capacidad instalada (¡y mantenida!) por terceros
  2. La facilidad para extender la funcionalidad de nuestra aplicación (Basta con realizar las llamadas al servicio web que deseamos)

La principal desventaja de usar este enfoque es que dependemos de servicios de terceros que, salvo en casos muy puntuales, no podemos controlar.

Ejemplos de webservices:

  1. Autenticación de usuarios vía Facebook, Google, Twitter, etc…
  2. Generación de mapas en tiempo real
  3. Consulta de cotizaciones de acciones

Qué es RESTful

RESTful es un modelo arquitectónico de software que plantea una suerte de volver a las fuentes. Su filosofía se basa en el poder del protocolo HTTP (Subyacente en toda aplicación web), el cual incluye los conceptos de verbo (GET, POST, DELETE, PUT) y recurso, código de errores (404, 500, etc…) y demás elementos que, en teoría al menos, deberían alcanzar para modelar cualquier tipo de interacción cliente-servidor.

Es muy común que en una aplicación RESTful los objetos o entidades del modelo de datos sean expuestos casi directamente, teniendo una URL específica para cada uno de ellos.

Por ejemplo, en una aplicación diseñada para una institución educativa sería esperable encontrarse con una URL de tipo:

http://miescuela.com/alumnos

Al realizar una petición de tipo GET a esta URL se esperará recibir información de los alumnos de esa institución.

A su vez, una URL del tipo:

http://miescuela.com/alumnos/14

Debería darme información del alumno cuyo id es 14.

Existe mucha controversia respecto de qué es una API RESTful y qué no lo es… Sin entrar en mayor detalle, la idea es que, para consumir un servicio web basado en REST sólo se requiere conocer su URL (De nuevo, esto es en teoría… en la práctica se utilizan varias formas de modifiación del pedido, como ser el envío de headers y demás).

Cómo se comunican cliente y servidor

Siendo que se trata de un servicio RESTful, la comunicación entre cliente y servidor es sencilla (A diferencia de lo que es un WebService SOAP), se trata simplemente de enviar un pedido HTTP y procesar su respuesta.

Existen varias opciones disponibles, veamos las más comúnmente utilizadas:

cURL

La librería cURL permite realizar peticiones a servidores remotos. Si bien funciona, es un método de bastante bajo nivel, con sus pros y sus contras.

Volviendo al ejemplo que te comentaba antes, una forma de hacer la llamada sería esta:

<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "http://miescuela.com/alumnos");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$res = curl_exec($ch);

curl_close($ch);

En la variable $res quedará la respuesta del webservice (Asumiendo por supuesto que no haya habido ningún problema de conexión, transferencia, etc…).

file_get_contents

Una opción alternativa (y generalmente más conveniente) es el uso de la función file_get_contents. Esta función recibe como parámetro el nombre del archivo que se quiere leer y devuelve todo su contenido como un string.

Si bien el uso normal de la función es la lectura de archivos locales, php en realidad entiende a los archivos como flujos. Por lo tanto, si está todo bien configurado, una URL puede usarse como nombre de un flujo.

De este modo nos ahorramos muchas de las complicaciones propias de tratar con una interface de más bajo nivel (y, obviamente, perdemos cierto control, pero generalmente no es necesario hilar tan fino).

El ejemplo sería:

<?php
$res = file_get_contents("http://miescuela.com/alumnos");

Cómo se procesan los resultados

Los resultados se procesan de acuerdo al formato de la respuesta. Usualmente los Servicios Web devuelven XML o JSON (Existen otras posibilidades, claro, pero estas son las más comunes).

En el caso de tratarse de un XML, lo mejor es usar la biblioteca SimpleXML, si se trata de json, con json_decode será suficiente (Si se trata de otro formato habrá que estudiar el caso puntual, pero en última instancia, siempre se trata de procesar un string…).

Un ejemplo real

MercadoLibre tiene una API RESTful que permite interactuar con el sitio de forma simple.

Veamos un ejemplo de una llamada de acceso público: la que nos da información básica de un usuario.

La URL que se utiliza es https://api.mercadolibre.com/users/USERID/, por ejemplo https://api.mercadolibre.com/users/226384143/

El valor retornado es un string JSON.

El código completo para obtener esta información con php es:

<?php

echo file_get_contents('https://api.mercadolibre.com/users/226384143/');

Claro que si quisiéramos hacer algo con esta información sería más conveniente hacer algo como:

<?php

$data = json_decode( file_get_contents('https://api.mercadolibre.com/users/226384143/'), true );

echo $data['nickname'];

¡Listo! Ya estás en condiciones de integrar cualquier WebService RESTful en tu aplicación.

¿Tenés algún ejemplo de servicio del que te hayas querido aprovechar? ¿Tuviste alguna dificultad? ¡Comentalo y te ayudamos!

mchojrin

Docente y consultor PHP at Leeway Academy
Ayudo a desarrolladores PHP a acelerar su llegada a Sr.

24 comentarios en “Cómo consumir un WebService REST con PHP

  • Hola! Gracias por el artículo. A quien me pueda ayudar: Crees que esta es la mejor forma para que mi App móvil Android/iOS rescate datos de mi base de datos en mi servidor? Planeo usar Ionic para la App. Gracias!

    • Hola!

      Gracias por tu comentario :). No conozco mucho de Ionic pero imagino que se podrá consumir un RESTful webservice de modo similar.

      En este artículo explico cómo hacerlo utilizando PHP.

      Lo que deberías hacer es que tu aplicación Android se comunique con un backend y el backend sea el que rescate los datos de tu base.

      Ese backend lo puedes desarrollar en PHP sin problemas y luego exponer los datos rescatados a través de un servicio REST para que lo consuma tu app. Puedes ver cómo hacer eso en este artículo: https://academy.leewayweb.com/como-exponer-un-webservice-rest-con-php/

      Saludos!

  • Miguel

    Hola, soy nuevo desarrollando, he leído sobre web services pero no lo tengo muy claro, Actualmente estoy desarrollando un app que hace reservaciones. El avance que tengo es el registro y login comunico los datos en una web services en php y bd en mysql. Para hacer la reservación me dicen que tiene que ser en tiempo real ya que el administrador debe ver la solicitud de reservación apenas la genere el cliente, la consulta es si hago el código respectivo para guardar la reservación mediante web service que tengo, esta acción no es en tiempo real?. Que tendría que implementar para que el administrador vea la solicitud en tiempo real. Apreciaría mucho su respuesta y muchas gracias!

    • Hola Miguel:

      Para empezar te diría que no te vuelvas muy loco :). El término «tiempo real» suele estar mal utilizado (Te dejo acá una referencia a la definición formal: https://es.wikipedia.org/wiki/Sistema_de_tiempo_real). En tu caso, imagino que un retraso de 5 minutos no va a cambiarle la vida a nadie (Y para tiempos computacionales ¡5 minutos es un montón de tiempo!).

      Respecto de la pregunta, es un poco difícil de responder sin ver el contexto así que haré algunos supuestos:

      – Asumiendo que el administrador tiene acceso a la misma aplicación donde se realizan las reservas, algo que podrías hacer es utilizar un mecanismo de polling (https://es.wikipedia.org/wiki/Polling) que se comunique desde el frontend con un webservice que tengas en tu servidor. Este WS debería chequear en la base de datos las reservas generadas desde la última consulta y retornar esos datos (Probablemente como json). Con esa información, desde el frontend podrías mostrar algún popup y listo.
      Otra opción similar es usar push notifications (https://blog.embluemail.com/como-funciona-push-notifications/).
      – Si el administrador no tiene acceso a la aplicación deberás enviarle las notificaciones de alguna otra forma (Por mail, sms, whatsapp, etc…). En este caso sería importante que la notificación se dispare apenas se recibe la reserva en tu sistema.
      – Si el administrador tiene su propia aplicación (Un CRM por ejemplo), seguramente requiera que tu aplicación exponga alguna API a través de la cuál el pueda integrar su sistema y ver las reservas como le sea más conveniente.

      Creo que con eso tienes para entretenerte un rato 🙂

    • Hola Luis:

      Muchas gracias por tu comentario. El modo de enviar la API Key y el API secret dependen de cómo los espera recibir el servicio al que quieres conectarte.

      Usualmente esos datos se envían a través de encabezados HTTP, deberías hacer algo como:

      curl_setopt($ch, CURLOPT_HTTPHEADER, [
      ‘X-API-Key: AAAAEEEECCCCCC’,
      ‘X-API-Secret: Th1S1sSup3rS3cr3t’
      ]);

      Antes de enviar la petición cURL o, si vas a usar file_get_contents:

      $opts = [
      «http» => [
      «method» => «GET»,
      «header» => «X-API-Key: AAAAEEEECCCCCC\r\nX-API-Secret: Th1S1sSup3rS3cr3t\r\n»
      ]
      ];

      $context = stream_context_create($opts);

      $file = file_get_contents($serviceURL, false, $context);

  • Rama

    Hola, muchas gracias por el post. Queda claro como consumir un WS pero quisiera saber como generar un Web Service yo similar al de Mercado Libre el cual devuelve la info de un usuario si existe ese ID. Quisiera saber como generarlo para que alguien pueda ejecutar una consulta a mi base de datos enviando, por ejemplo, el DNI de una persona y yo devolverle los datos de la misma en caso de existir.

  • NachoV

    Genial Mchojrin, muy claro y simple! Te consulto, como hacer para leer respuesta del tipo «ok 200» porque esto viene en el encabezado del mensaje. Muchas gracias! PD ya me suscribí!

  • Sergio ORtega

    Excelente el aporte, te felicito. Agradezco si me puedes ayudar a resolver mi inconveniente. Estoy haciendo pruebas desde mi localhost, consumo los datos perfecto, una vez publicado mi proyecto, se recibe codigo 404. inclusive hago pruebas con postman y fiddler, todas con codigo 200 Ok,

    • Muchas gracias Sergio! Me alegro que te haya servido :). ¿Cómo es eso de «una vez publicado»? ¿Te refieres a cuando lo subes a un hosting?

      Lo que deberías verificar primero que nada es si desde la máquina donde estás realizando las pruebas tienes conectividad al servidor al que estás tratando de acceder… imagino que sí porque si te responde con un 404 eso quiere decir que hay un webserver del otro lado…

      Otra cosa que puede pasar es que el webserver esté mal configurado y, por lo tanto, no esté dirigiendo correctamente las peticiones hacia tu webserver.

    • Pues eso depende de la especificación del webservice al que te estés queriendo conectar… ¿Quién genera el token? ¿Cómo lo obtienes? ¿Cómo lo envías? Con esas respuestas podrás ver el código que debes escribir.

      • Este es el codigo que genera el token,
        «http://191.98.194.210/casospropiosapi2/token»,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => «»,
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => «POST»,
        CURLOPT_POSTFIELDS => «username=uXXXXXX&password=XXXXXXXX&grant_type=password&undefined=»,
        CURLOPT_HTTPHEADER => array(
        «Content-Type: application/x-www-form-urlencoded»,
        «Postman-Token: af6dfe86-d223-4926-bdf6-8f357c4b3b33»,
        «cache-control: no-cache»
        ),
        ));

        $atoken = curl_exec($curl);
        $err = curl_error($curl);

        curl_close($curl);

        if ($err) {
        echo «cURL Error #:» . $err;
        } else {
        echo $atoken;
        }

        ?>

        Se ve algo asi:

        {«access_token»:»x-kuOcfpZAAV-MaNqbWU3n25dNKlRuuK6JHYVpXb1gxnzsAj8KwLlAorpLMFeZNQ4MCwe4Sd2-YvSLLQqoLBo4fehYJuQasXupv9MYcMZYa5XgdRqcWYZjVp9omnqh0h3iapVwbsUlyelYH1QiXyHMMIqFvwns7vwUZOmkRMef4PX2soLe7pUHuq10N5BryWR2EcLFFepbsq-KerhoRlMD_SguvoCBC-ajxdvZQlqZIr4um1brbT_Tf6MpZjgoC9fuqR-WfjQzG4cSnSENv6ukFQo7FiaAxbP19qwYdij-fHNT2hhcOnT_7vPZtqfX_A»,»token_type»:»bearer»,»expires_in»:599}

        Luego de generarlo, lo tengo que usar para usar la api:

        «http://191.98.194.210/casospropiosapi2/api/casasdisponibles/authenticate»,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => «»,
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => «GET»,
        CURLOPT_POSTFIELDS => «username=usuario_web&password=snY8SOUEHxQxyCbFd0rDgQ%3D%3D&grant_type=password&undefined=»,
        CURLOPT_HTTPHEADER => array(
        «Authorization: bearer AQUI COPIO TODO EL CODIGO QUE SE GENERA ANTERIOMENTE «,
        «Postman-Token: d09935ae-dcbb-44c2-b662-4b0f8fb26007»,
        «cache-control: no-cache»
        ),
        ));

        $respuesta = curl_exec($casas);
        $err = curl_error($casas);

        curl_close($casas);

        if ($err) {
        echo «cURL Error #:» . $err;
        } else {
        echo $respuesta;

        }
        ?>

        • No sé si estoy entendiendo bien tu duda… por lo que veo el código de obtener y enviar el token lo tienes resuelto…

          Lo que imagino que te está complicando la historia es lo del vencimiento cada 15 minutos, ¿es así? En tal caso lo que podrías hacer es guardar el token actual en un archivo de texto (en algún directorio seguro) y leerlo cada vez que tienes que enviar un nuevo pedido.

          Paralelamente podrías tener un cronjob corriendo cada 15 minutos para generar un nuevo token y guardarlo en ese mismo archivo para que esté disponible para el próximo pedido.

  • davd

    hola amigo aun no he consumido ninguna api rest y quiero aprender a hacerlo desde cero me puedes ayudar en algo de como empezar etc algun tutorial o algo , uso php , gracias

    • Hola Marcos:

      Gracias por tu pregunta! Todo depende de cómo esté armada la API a la que te estás conectando. Puede ser que requiera que le envíes json, tal vez XML o tal vez usa algún otro mecanismo de recepción de parámetros…

      En todo caso, lo que seguramente tendrás que hacer será realizar un POST al servidor.

      Saludos

  • Estoy desarrollando una web de reservas de ciertos locales. La idea es que puedan reservar desde mi web en otros locales de tal manera que , en mi web, salgan los datos actualizados de las reservas de ese local. ¿Cómo lo implemento? ¿Necesito que el local(que tienen web) me proporciones una API Rest?. Ayúdame por favor.

    Gracias

    • Hola:

      Si los locales tienen una API REST (O pueden desarrollarla) puede ser una buena solución. Lo importante es que tengas un modo de mantener todo sincronizado… Si los locales son todos tuyos podrías tener una única base de datos centralizada a la que todos accedan mediante alguna conexión segura o algún tipo de middleware con el que todos se comuniquen… habría que ver un poco más el contexto.

      El punto es que necesitarás algún mecanismo para consultar las reservas que se hicieron en cada local y para «inyectar» tus propias reservas en cada uno.

      Esto puede resolverse bien con algúna API (Sea REST, SOAP u otra)

¿Te quedó alguna duda? Publica aca tu pregunta

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

A %d blogueros les gusta esto: