lunes, 23 de septiembre de 2013

Servicios web (webservices) con REST sobre CodeIgniter

PRIMERA PARTE

Acoplar bibliotecas para brindar servicios webs (webservices) sobre CodeIgniter, como en tantos otros casos, resulta extremadamente sencillo si has encontrado la biblioteca correcta. La complicación podría venir posteriormente cuando quieras utilizar las funcionalidades de la biblioteca utilizada. En este artículo te mostraré como utilizar dos tendencias: REST y SOAP, sobre CodeIgniter.

REST (Representational state transfer: transferencia representacional de estados), es un estilo que abstrae los elementos arquitectónicos en un sistema de hipermedia distribuido. REST ignora los detalles de implementación de los componentes y la sintaxis del protocolo, enfocándose en los roles de los componentes, su interpretación y la interacción con otros componentes. Ha emergido y es predominante como un API modelo de diseño web.

SOAP (Simple Object Access Protocol: protocolo de acceso a objetos) es un estándar que define cómo dos objetos en diferentes procesos pueden comunicarse por medio de intercambio de datos XML. Cuenta con buena extensibilidad, neutralidad (puede ser utilizado sobre cualquier protocolo de transporte como HTTP, SMTP, TCP o JMS) e independencia (permite cualquier modelo de programación).

Ambas tecnologías son buenas según tu objetivo. En internet se suele decir que REST es muy fácil de utilizar (por su abstracción) pero se recomienda para sistemas sencillos, en cambio SOAP es bastante difícil de utilizar (por ser tan genérica y flexible) y se recomienda para sistemas más complejos. Así que lo primero es definir qué modelo utilizarás según la complejidad de tu sistema.

En este artículo te mostraré ambas formas. Mi intención no es que entiendas perfectamente el funcionamiento de estas bibliotecas ni que aprendas a usarlas con solo leer este artículo. Solo quiere que te lleves la idea de la diferencia de complejidad en el uso de una u otra biblioteca, y que te sirva como punto de partida para buscar más información y brindar servicios web seguros y robustos. A la vez, demostrarte la facilidad con que ambas bibliotecas se integran con CodeIgniter.

REST

Para trabajar con REST en CodeIgniter te recomiendo descargar la biblioteca “CodeIgniter Rest Server” [2] (para PHP 5.2 o mayor y del CodeIgniter 2.1.0 al 3.0-dev). También puedes descargar el “CodeIgniter Rest Client” [3] si lo que deseas es consumir servicios. En mi caso solamente me interesa publicarlos.

Por cierto, si quieres consumir servicios con REST necesitas trabajar con cURL que te permite encapsular los datos que le pasas al servidor. Para esto puedes usar la biblioteca “CodeIgniter Curl library” [4].

Una vez descargada y descompactada la “CodeIgniter Rest Server”, notarás que es todo un proyecto de CodeIgniter con sus carpetas application y system. De esto solamente necesitas copiar “Format.php” y “REST_Controller.php” del application/libraries de la biblioteca para la carpeta application/libraries de tu sitio; y el fichero “rest.php” del application/config de la biblioteca para el application/config de tu sitio.

Luego adicionas un controlador con cualquier nombre, que herede de REST_Controller:

class Services_rest extends REST_Controller

Y listo, ya tienes acoplada la biblioteca a tu proyecto de CodeIgniter.

El segundo paso sería utilizar la biblioteca. Dado que puedes recibir peticiones por GET o por POST, la manera de que CodeIgniter Rest Server entienda cuál es la función adecuada es poniendo el sufijo get o post al final de las funciones. Por ejemplo el método students_get se ejecutará cuando se llame al servicio “students” vía GET, y el método students_post se ejecutará cuando se llame al servicio “students” vía POST. También existen los sufijos para PUT y DELETE.

En este link [1] podrás encontrar un tutorial muy completo de cómo acoplar CodeIgniter Rest Server a CodeIgniter, y te explica también cuándo y cómo usar PUT y DELETE, las ventajas y cómo usar cURL para consumir los servicios, etc.

Un ejemplo de una función-servicio con REST podría ser (dentro del controlador services_rest):

function students_get()
{
$result = new Response_students();

$id = $this->get('id');
$this->load->model('students_model');
$student = $this->students_model->get_student($id);

if (!empty($equipment))
{
$result->responseCode = 0;
$result->responseMessage = 'Equipo encontrado';
$result->student_data = $student;
}
else
{
$result->responseCode = 1;
$result->responseMessage = 'El estudiante no existe';
$result-> student_data = null;
}

$this->response($result, 200);
}

“Response_students” es una clase que creé para gestionar mejor los códigos y mensajes de errores, pero se puede retornar simplemente $this->response($student, 200) con los resultados sacados de una BD en forma de tabla, sin importar si es una fila o varias (por eso se destaca el nivel de abstracción de REST). El resultado se enviará al cliente sin problema alguno (el 200 es un código de respuesta, como 400, 404, etc).


Esta función como habrás notado se llamará vía GET y recibe un “id”. La forma de llamarla para comprobar sería:

http://sitio/services_rest/id/25 (sitio / controlador / nombre del parámetro / valor del parámetro, puedes ver en [1] una mejor explicación de esta sintaxis).

Puesto así se retorna una estructura XML que puedes ver directamente en tu navegador. Si lo quisieras en otro formato simplemente pondrías /format/el_formato, por ejemplo:

http://sitio/services_rest/id/25/format/json

Si la función fuera para ser utilizada por POST, capturarías el parámetro con $id = $this->post('id').

Con esto ya tienes montado tu servidor de webservices con REST y cada función es muy sencilla de implementar, con la facilidad de que REST traduce tus datos enviados por response a varios formatos de salida sin importar el tipo de dato proveniente de la BD (int, string…).

Faltaría prevenir que cualquiera teclee la dirección en la barra y acceda a tus datos o acceda al servicio sin autorización. Para esto entras a application/config/rest.php y pones:

$config['rest_auth'] = 'digest';   //línea 62
$config['rest_valid_logins'] = array(
'user1' => 'pass1',
'user2' => 'pass2'); //línea 109


Terminado. En la segunda parte de este artículo te hablaré entonces sobre el trabajo son la biblioteca nusoap sobre CodeIgniter.

Referencias:

[1] Working with RESTful Services in CodeIgniter,

http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/

[2] Descarga de biblioteca CodeIgniter Rest Server:

http://github.com/philsturgeon/codeigniter-restserver

[3] Descarga de biblioteca CodeIgniter Rest Client:

http://github.com/philsturgeon/codeigniter-restclient

[4] Descarga de biblioteca CodeIgniter Curl library:

http://getsparks.org/packages/curl/show


¿Te ha gustado este Post? Compártelo con tus amigos.

4 comentarios:

  1. Muy buenas, muy currado el tutorial, de verdad que ayuda mucho.

    A mi me surgen un par de dudas:

    Que diferencia hay entre el cliente y el server?
    Se le puede meter alguna libreria de auth para mejorar la seguridad?

    Muchas gracias por todo

    ResponderEliminar
  2. Fenomenal el tuto. Da gusto encontrarse con información tan bien explicada.

    ResponderEliminar
  3. Muy bueno. Sólo agregaría mover el archivo rest_controller_lang.php a la carpeta application/language/english/. Yo usé las veriones CI 3.1.4 y CodeIgniter Rest Server.

    ResponderEliminar

IconIconIcon