En esta entrada te muestro la implementación de un servicio web RESTful con PHP, que nos permite realizar operaciones CRUD sobre una tabla de usuarios en una base de datos SQLite:
URL |
HTTP Verb |
Cuerpo de la petición |
Resultado |
api/usuarios |
GET |
– |
Obtener la lista completa de usuarios |
api/usuarios/{id} |
GET |
– |
Obtener el usuario con el identificador {id} |
api/usuarios |
POST |
un nuevo usuario |
Crea el nuevo usuario y lo devuelve en el cuerpo de la respuesta con el id que se le ha asignado |
api/usuarios/{id} |
PUT |
un usuario existente modificado |
Modifica el usuario y lo devuelve en el cuerpo de la respuesta |
api/usuarios/{id} |
DELETE |
– |
Borra el usuario con el identificador {id} |
Fichero .htaccess
En un fichero de script PHP, podemos implementar sin grandes dificultades, la gestión de peticiones con los diferentes verbos GET, POST, PUT y DELETE. Pero, necesitamos un sistema de enrutamiento para las url de tipo api/usuarios/{id}. Una solución, sería escribir una regla Rewrite en un fichero .htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/([0-9]+)$ $1.php [L]
Con esto tanto las peticiones a la URL api/usuarios/{id}, como a la URL api/usuarios se procesan en api/usuarios.php. El id no lo perdemos, porque lo podemos sacar de la variable $_SERVER[‘REQUEST_URI’].
Clase ClienteSQLite – sqlite.php
Para facilitar el acceso a la base de datos SQLite, he creado la siguiente clase:
<?php
class ClienteSQLite
{
private $lastInsertId=0;
public function Command($comando,$params=array())
{
$myArray =array();
$conn = new PDO('sqlite:../db/dap.db');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$statement = $conn->prepare($comando);
$statement->execute($params);
$this->lastInsertId = $conn->lastInsertId();
$myArray = $statement->fetchAll(PDO::FETCH_OBJ);
$conn = null;
return $myArray;
}
public function LastInsertId()
{
return $this->lastInsertId;
}
}
?>
Servicio web RESTful – usuarios.php
El código del servicio web RESTful en PHP es el que se muestra a continuación:
<?php
require 'sqlite.php';
/*******RESPUESTA EN FORMATO JSON********/
function sendJSONResponse($body, $statusCode)
{
header("Content-Type: application/json; charset=UTF-8");
http_response_code($statusCode);
echo(json_encode($body));
}
/*******OBTENER EL IDENTIFICADOR DE LA PETICION REST********/
function getLastPartURL()
{
$lastPartURL=array_pop(explode('/', $_SERVER['REQUEST_URI']));
return $lastPartURL;
}
/*******OBTENER EL CUERPO JSON DE LA PETICION HTTP********/
function getJSONBody()
{
$inputJSON = file_get_contents('php://input');
$objeto= json_decode( $inputJSON );
return $objeto;
}
/*********SCRIPT CONTROLADOR DE USUARIOS*********/
$clienteSQL=new ClienteSQLite();
switch ($_SERVER['REQUEST_METHOD']) {
case 'POST':
try
{
$objeto= getJSONBody() ;
$params=array(':nombre' => $objeto->Nombre,':password' => $objeto->Password);
$clienteSQL->Command("INSERT INTO Usuarios (Nombre, Password) VALUES (:nombre,:password)",$params);
$objeto->UsuarioId=$clienteSQL->LastInsertId();
sendJSONResponse($objeto,"200");
}
catch(Exception $e)
{
sendJSONResponse(array("Error al crear usuario"), 500) ;
}
break;
case 'PUT':
try
{
$lastPartURL=getLastPartURL();
if (is_numeric($lastPartURL))
{
$objeto= getJSONBody() ;
$params=array(':id' => $lastPartURL, ':nombre' => $objeto->Nombre,':password' => $objeto->Password);
$clienteSQL->Command("UPDATE Usuarios SET Nombre=:nombre,Password=:password WHERE UsuarioId=:id",$params);
sendJSONResponse($objeto,"200");
}
else
{
sendJSONResponse(array("Formato de URL no válido"), 500) ;
}
}
catch(Exception $e)
{
sendJSONResponse(array("Error al actualizar usuario"), 500) ;
}
break;
case 'GET':
try
{
$lastPartURL=getLastPartURL();
if (is_numeric($lastPartURL))
{
$params=array(':id' => $lastPartURL);
$myArray=$clienteSQL->Command("SELECT * FROM Usuarios WHERE UsuarioId=:id",$params);
if (count($myArray)==1)
sendJSONResponse($myArray[0],"200");
else
http_response_code(204);
}
else
{
$myArray=$clienteSQL->Command("SELECT * FROM Usuarios");
if (count($myArray)>0)
sendJSONResponse($myArray,"200");
else
http_response_code(204);
}
}
catch(Exception $e)
{
sendJSONResponse(array("Error al consultar usuario/s"), 500) ;
}
break;
case 'DELETE':
try
{
$lastPartURL=getLastPartURL();
if (is_numeric($lastPartURL))
{
$params=array(':id' => $lastPartURL);
$clienteSQL->Command("DELETE FROM Usuarios WHERE UsuarioId=:id",$params);
http_response_code(204);
}
else
{
sendJSONResponse(array("Formato de URL no válido"), 500) ;
}
}
catch(Exception $e)
{
sendJSONResponse(array("Error al borrar usuario"), 500) ;
}
break;
}
?>