lunes, 5 de agosto de 2013

Servicio Web RESTful con Php

La creación de Servicios Web esta hoy en día en un total auge debido a la proliferación de las aplicaciones para dispositivos móviles. Los servicios web nos permiten distribuir los datos entre distintos tipos de aplicaciones, páginas Web, etc. Estos servicios Web generarán una respuesta a una petición realizado por un cliente del servicio, respuesta que generalmente será en formato JSON o XML


El ejemplo que os muestro a continuación está basado en el artículo incluido en http://www.9lessons.info/2012/05/create-restful-services-api-in-php.html el cual generará una respuesta JSON. El código principal de la API RESTful será la siguiente:

<?php
require_once("Rest.inc.php");

class
 API extends REST { 
  public $data = ""; 
  const DB_SERVER = "localhost";
  const DB_USER = "Database_Username"; 
  const DB_PASSWORD = "Database_Password";
  const DB = "Database_Name";
  private $db = NULL; 
  public function __construct()
  {
    parent::
__construct();// Init parent contructor
    $this->
dbConnect();// Initiate Database connection
  }
 

  //Database connection
  private function dbConnect()
  {     $this->db=
mysql_connect(self::DB_SERVER,self::DB_USER,self::DB_PASSWORD);
    if($this->db)
mysql_select_db(self::DB,$this->db);
  }
 

  //Public method for access api.
  //This method dynmically call the method based on the query  string
  public function processApi()
  {
    $func =
 strtolower(trim(str_replace("/","",$_REQUEST['rquest'])));
    if((int)method_exists($this,$func) > 0)
      $this->$func();
    else
      $this->
response('',404); 
    // If the method not exist with in this class, response would be "Page not found".
  }


  private function login()
  {
    ..............
  }


  private function users()
  {
    ..............
  }
 

  private function deleteUser()
  {
    .............
  }


  //Encode array into JSON
  private function json($data)
  {
    if(
is_array($data)){
      return
 json_encode($data);
    }
  }
}
 

// Initiiate Library
$api = new
 API;
$api->
processApi(); 
?>

En el API se establecen los valores de conexión con la base de datos MySql y las funciones necesarias para realizar dicha conexión. A continuación crearemos tres métodos: login(), que realizará la función de autentificación de un usuario en la base de datos; users(), que nos devolverá una lista de los usuarios que tengamos la tabla de base de datos; y el método deleteUser(), el cual borrará un usuario.

Login: será una petición del tipo POST. En la petición se enviarán dos parámetros, “email” y “pwd”. La función lo primero que hace es comprobar el tipo de petición y que sea del tipo POST, en caso contrario enviara una respuesta de error 406 (en el fichero Rest.inc.php se pueden consultar las posibles respuestas). Una vez recibida la petición se verificarán los parámetros enviados, se consultará a la base de datos y en caso de que los datos sean correctos se devolverá la respuesta JSON con los datos del usuario y las correspondientes cabeceras de que la consulta se realizo correctamente (200).


private function login()
{
 
  // Cross validation if the request method is POST else it will return "Not Acceptable" status
  if($this->
get_request_method() != "POST")
  {
     $this->
response('',406);
  }

  $email = $this->
_request['email'];
  $password = $this->
_request['pwd']; 

  // Input validations
  if(!
empty($email) and !empty($password))
  {
    if(
filter_var($email, FILTER_VALIDATE_EMAIL)){
      $sql =
 mysql_query("SELECT user_id, user_fullname, user_email FROM users WHERE user_email = '$email' AND user_password = '".md5($password)."' LIMIT 1", $this->db);
      if(
mysql_num_rows($sql) > 0){
        $result =
 mysql_fetch_array($sql,MYSQL_ASSOC); 
        // If success everythig is good send header as "OK" and user details
        $this->
response($this->json($result), 200);
      }
      $this->
response('', 204);  
      // If no records "No Content" status
    }
   }
 
   // If invalid inputs "Bad Request" status message and reason
   $error =
 array('status' => "Failed", "msg" => "Invalid Email address or Password");
   $this->
response($this->json($error), 400);
}

Users: será una petición del tipo GET. Al igual que en login(), lo primero que haremos será comprobar el tipo de petición. Si la petición es correcta se realizará la consulta SQL y se devolverá la lista de usuarios en formato JSON.


private function users()
{

  // Cross validation if the request method is GET else it will return "Not Acceptable" status  

  if($this->get_request_method() != "GET")
  {
    $this->
response('',406);
  }
  $sql =
 mysql_query("SELECT user_id, user_fullname, user_email FROM users WHERE user_status = 1", $this->db);
  if(
mysql_num_rows($sql) > 0)
  {
    $result =
 array();
    while($rlt = mysql_fetch_array($sql,MYSQL_ASSOC))
    {
      $result[] = $rlt;
    }
 
    // If success everythig is good send header as "OK" and return list of users in JSON format
    $this->
response($this->json($result), 200);
  }
  $this->
response('',204); // If no records "No Content" status
}

DeleteUser: como siempre lo primero es verificar el tipo de petición, posteriormente recibimos el parámetro “id” que será el usuario a borrar de nuestra tabla. Si todo es correcto ejecutamos la consulta SQL y lanzamos la correspondiente respuesta JSON confirmando la acción.


private function deleteUser()
{
  if($this->
get_request_method() != "DELETE"){
    $this->
response('',406);
  }
  $id = (int)$this->_request['id'];
  if($id >
 0)
  {

    mysql_query("DELETE FROM users WHERE user_id = $id");
    $success =
 array('status' => "Success", "msg" => "Successfully one record deleted.");
    $this->
response($this->json($success),200);
  }
  else
  {
    $this->
response('',204); // If no records "No Content" status
  }
}

Hasta aquí hemos visto como desarrollar las funciones básicas para desarrollar nuestra API RESTful. Para probar su funcionamiento podemos utilizar una extensión para Chrome: AdvancedREST client Application

Adicionalmente, podemos crear un fichero .htaccess para generar URLs amigables y que las llamadas a los métodos de nuestro servicio sean mas sencillas. El fichero .htaccess:

<IfModule mod_rewrite.c>
RewriteEngine
 On
RewriteCond %{
REQUEST_FILENAME} !-d
RewriteCond %{
REQUEST_FILENAME} !-s
RewriteRule ^(.*)$
 api.php?rquest=$1 [QSA,NC,L]

RewriteCond %{
REQUEST_FILENAME} -d
RewriteRule ^(.*)$
 api.php [QSA,NC,L]

RewriteCond %{
REQUEST_FILENAME} -s
RewriteRule ^(.*)$
 api.php [QSA,NC,L]
</IfModule>

Y para hacer las llamadas a los métodos del servicio seria:
http://mi_dominio.com/ruta_del_servicio/login
http://mi_dominio.com/ruta_del_servicio/users
http://mi_dominio.com/ruta_del_servicio/DeleteUser

Puedes descargar el ejemplo completo desde aquí.

3 comentarios :

  1. No funcan las llamadas a cualquiera de estos servicios,
    segun la pagina un comentario dice que se hace asi
    http://localhost/rest/api.php?rquest=users para users, pero no consigo para login, ni menos crear un metodo con get que me reciba parametros, sabes como puedo hacer que reciba?

    ResponderEliminar
  2. a mi tampoco me funciona esta clase, lo mismo, me devuelve una página en blanco

    ResponderEliminar
  3. hola, si funciona, haz un test con la extensión AdvancedREST client Application para chrome, en url pon la amigable: http://localhost/rest/login, elige el tipo "Post" e ingresa los parámetros como values form del tipo payload: email y pwd, ojo debes ingresar un email valido, enviar y te devuelve la data en formato json, slds.

    ResponderEliminar