Crear Un Web Service API Rest Con PHP y MySQL
Crear Un Web Service API Rest Con PHP y MySQL
Crear Un Web Service API Rest Con PHP y MySQL
y MySQL
JSON MySQL PHP Anthony Medina 22:46
Los API Rest son en la actualidad la nueva manera de trabajar los sistemas web, los
mismos se encargan de servir la información que luego sera consumida por algún
cliente, usualmente usando alguna librería JavaScript como jQueryo AngularJS.
Los Web Services no son mas que archivos en formato JSON que sirven los datos de
una base de datos de una manera mas dinámica y apreciable, estos proporcionan las
acciones que desde tiempo remotos trabajan las paginas web dinámicas, el tipo
CRUD (Create-Read-Update-Delete) son ahora manejados de una forma mas sencilla
usando un Web Services API Rest y los métodos HTTP.
De seguro si, alguna vez al escuchado el típico método POST o Método GET, de los
cuales haremos uso en este post, además de los no tan mencionados pero ya
bastante conocidos método PUT y DELETE.
Los códigos de cabecera HTTP definen el status actual de una pagina o documento
con respecto a la solicitud realizada, de seguro que hemos visto el tipico error 404, en
este tutorial haremos uso de los mostrados con posterioridad, sin embargo, te dejo
este articulo de Wikipedia que te ayudara a comprender mejor de que trata.
Códig
Definición Uso o Aplicaron
o
201 Created Se aplicara cuando para cada entidad se cree un nuevo elemento
Postman o Insomnia
Para efectos de prueba haremos uso de una extensión para Chrome como aplicacion,
entre ellas podemos mencionar dos herramientas realmente muy amigables
como Postman o Insomnia, yo en lo particular, sugiero el uso de Insomia. Recuerden
que necesitamos hacer uso de los mismos ya que el navegador por defecto ejecuta
solamente el metodo GET, para firefox, puedes hacer uso de la extensión Firebug.
JSON y XML
Los estándares JSON y XML son con peculiaridad los lenguajes usados para servir
datos desde un Web Services. Los lenguajes son equivalente, con la única diferencia
de que su sintaxis tienen su particularidad. He aqui algunos ejemplos.
Ejemplo de JSON (JavaScript Object Notation)
{
"statusCode": 200,
"statusMessage": "OK",
"data": [
{
"Id": "1",
"Usuario": "admin",
"Clave": "21232f297a57a5a74389",
"Status": "1"
}
]
}
No haré mucho énfasis en explicar el código para crear el Web Services ya que el
código mismo esta documentado, esta sera el directorio de la aplicaron.
Crea el directorio tal cual ves en la imagen en tu servidor y agrega los siguientes
códigos proporcionados a continuación
Antes de empezar, vamos a nuestro PhpMyAdmin para crear nuestra base de datos,
en mi caso, la llame Api, y ejecuta el siguiente código
api.sql
core/config.php
<?php
/*
* En este archivo se definiran la información de configuracion del API,
* variables, constantes y funciones requeridas para el resto de los archivos
*/
core/iModel.php
<?php
// Declarar la interfaz 'iModel'
// Define cada una de las funciones que el model.php debe especificar
interface iModel
{
// GET : Solicitar un elemento
public function get();
// POST : Publicar un nuevo elemento
public function post();
// PUT: Modificar un elemento
public function put();
// DELETE: Eliminar un elemento
public function delete();
}
?>
core/db_model.php
<?php
// Incluimos el archivo de configuración el cual posee las credenciales de conexión
include 'config.php';
// Variable de conexion
public $conn;
// Cierra la consulta
$result->close();
// Retorna el resultado
return $result;
model.php
<?php
// Se incluye el archivo de conexion de base de datos
include 'core/db_model.php';
// Se incluye la interfaz de Modelo
include 'core/iModel.php';
// Se crea la clase que ejecuta llama a las funciones de ejecución para interactuar con la
Base de datos
// Esta clase extiende a la clase db_model en el archivo db_model.php (hereda sus
propiedades y metodos)
// Esta clase implementa la interfaz iModel (Enmascara cada una de las funciones
declaradas)
class generic_class extends db_model implements iModel {
// Ya que la clase es generica, es importante poseer una variable que permitira
identificar con que tabla se trabaja
public $entity;
// Almacena la informacion que sera enviada a la Base de datos
public $data;
return $this->set_query(sprintf("
INSERT INTO
%s
%s",
$this->entity,
$this->data
)
);
}
$this->entity,
$this->Id
)
);
}
}
?>
controller.php
<?php
// Permite la conexion desde cualquier origen
header("Access-Control-Allow-Origin: *");
// Permite la ejecucion de los metodos
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
// Se incluye el archivo que contiene la clase generica
include 'model.php';
// Se toma la URL solicitada y se guarda en un array de datos
// Por ejemplo si la URL solicitada es http://localhost/api/usuario
// $_SERVER['REQUEST_URI'] imprime "/api/usuario"
// La funcion explode() crea un array de la URL de la siguiente forma
/*
Array
(
[0] =>
[1] => api
[2] => usuario
)
*/
// Por ejemplo si la URL solicitada es http://localhost/api/usuario/1
// $_SERVER['REQUEST_URI'] imprime "/api/usuario/1"
// La funcion explode() crea un array de la URL de la siguiente forma
/*
Array
(
[0] =>
[1] => api
[2] => usuario
[3] => 1
)
*/
// Esto nos ayuda a identificar cuando se esta solicitando la URL general o un elemento
especifico
$array = explode("/", $_SERVER['REQUEST_URI']);
/* Este ciclo rrecorre el array previamente creado y si hay algun valor en blanco lo
elimina del array
Esto con el fin de controlar cuando la URL se enviar en estilo
http://localhost/api/usuario/
Si bien, se esta haciendo uso del "/" al final, no se esta enviando ningun parametro de
Id
Sin embargo, el array se crea de la siguiente forma
Array
(
[0] =>
[1] => api
[2] => usuario
[3] =>
)
Ya que la ultima pocision esta vacia, si lo permitieramos asi, nos arrojaria un error ya
que no haria la
Solicitud de manera correcta con un dato que esta vacio, por lo que si la URL es enviada
del forma, se asume
que se esta realizando una solicitud general al estilo http://localhost/api/usuario
*/
foreach ($array as $key => $value) {
if(empty($value)) {
unset($array[$key]);
}
}
/* Analiza la ultima pocision del array creado previamente, si el valor analizado es mayor
que 0
significa que el caracter enviado es un numero, por lo tanto, reconocemos que la
solicitud se esta
haciendo a un Id especifico de tipo http://localhost/api/usuario/1, pero de no ser mayor
que 0, reconocemos que el ultimo elemento del array
es solo el nombre de la entidad, por lo tanto, reconocemos que se esta haciendo una
solicitud general
de tipo http://localhost/api/usuario
*/
if(end($array)>0) {
// De ser el valor numerico, crea dos variables que contienen el Id solicitado y la entidad
solicitada
$id = $array[count($array)];
$entity = $array[count($array) - 1];
} else {
// De ser el valor de tipo string, solo crea la variable de la entidad solicitada
$entity = $array[count($array)];
}
// Analiza el metodo usado actualmente de los cuatro disponibles: GET, POST, PUT,
DELETE
switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
// Acciones del Metodo GET
// Si la variable Id existe, solicita al modelo el elemento especifico
if(isset($id)) {
$data = $obj->get($id);
// Si no existe, solicita todos los elementos
} else {
$data = $obj->get();
}
// Elimina el ultimo elemento del array $data, ya que usualmente, suele traer dos
elementos, uno con la informacion, y otro NULL el cual no necesitamos
array_pop($data);
break;
case 'POST':
// Acciones del Metodo POST
/* Analiza si existe la variable Id, ya que la URL solicita por POST solo puede ser de
estilo
http://localhost/api/usuario no habria por que existir un Id ya que se esta registrando
un
nuevo elemento y el Id es autogenerado, si el Id no existe, entra en esta condicional */
if(!isset($id)) {
// Decodifica el cuerpo de la solicitud y lo guarda en un array de PHP
$array = json_decode($bodyRequest, true);
}
// Si la respuesta es false, se supone que el elemento no ha sido registrado, y entra en
este condicional
} else {
print_json(201, false, null);
}
// En tal caso de que exista la variable Id, imprimira el mensaje del que el metodo
solicitado no es correcto
} else {
print_json(405, "Method Not Allowed", null);
}
break;
case 'PUT':
// Acciones del Metodo PUT
if(isset($id)) {
// Consulta primeramente que en realidad exista un elemeto con el Id antes de
modificar
$info = $obj->get($id);
array_pop($info);
$obj->Id = $id;
$data = $obj->put();
if($data) {
$data = $obj->get($id);
if(count($data)==0) {
print_json(200, false, null);
} else {
array_pop($data);
print_json(200, "OK", $data);
}
} else {
print_json(200, false, null);
}
// Si la info recibida es igual a 0, el elemento no existe y no hay nada para modificar
} else {
print_json(404, "Not Found", null);
}
} else {
print_json(405, "Method Not Allowed", null);
}
break;
case 'DELETE':
if(isset($id)) {
$info = $obj->get($id);
if(count($info)==0) {
print_json(404, "Not Found", null);
} else {
$obj->Id = $id;
$data = $obj->delete();
if($data) {
array_pop($info);
if(count($info)==0) {
print_json(404, "Not Found", null);
} else {
print_json(200, "OK", $info);
}
} else {
print_json(200, false, null);
}
}
} else {
print_json(405, "Method Not Allowed", null);
}
break;
default:
// Acciones cuando el metodo no se permite
// En caso de que el Metodo Solicitado no sea ninguno de los cuatro disponible, envia la
siguiente respuesta
print_json(405, "Method Not Allowed", null);
break;
}
switch ($_SERVER['REQUEST_METHOD']) {
case 'POST':
# code...
foreach ($keys as $key => $value) {
if($key == count($keys) - 1) {
$str = $str . $value . ") VALUES (";
}
} else {
if($key == 0) {
$str = $str . "(" . $value . ",";
} else {
$str = $str . $value . ",";
}
}
}
return $str;
break;
case 'PUT':
foreach ($keys as $key => $value) {
if($key == count($keys) - 1) {
$str = $str . $value . "='" . $values[$key] . "'";
} else {
$str = $str . $value . "='" . $values[$key] . "',";
}
}
return $str;
break;
}
// Esta funcion imprime las respuesta en estilo JSON y establece los estatus de la
cebeceras HTTP
function print_json($status, $mensaje, $data) {
header("HTTP/1.1 $status $mensaje");
header("Content-Type: application/json; charset=UTF-8");
$response['statusCode'] = $status;
$response['statusMessage'] = $mensaje;
$response['data'] = $data;
.htaccess
Ahora, solo nos queda modificar el archivo .htaccess para poder acceder a las URL
sin errores, recuerden que para que esto funcione, el mod_rewrite de Apache debe
estar activado, de otra manera, todo el trabajo que has hecho, no serviría de nada.
RewriteEngine On
# Para metodo GET, POST, PUT
RewriteRule ^api/([a-zA-Z]+)$ controller.php
RewriteRule ^api/([a-zA-Z]+)/$ controller.php
# Expresiones regulares
## Alfanumericos | ([a-zA-Z0-9]+)
## Numericos | ([0-9]+)
## Caracteres | ([a-zA-Z]+)
GET api/usuario
POST api/usuario
GET api/usuario
GET api/usuario/7
PUT api/usuario/7
DELETE api/usuario/1
Luego de crear este Web Services, puedes crear cuantas tablas en la base de datos
desees, y en la URL solo debes cambiar el nombre de la entidad por el nombre de la
tabla en la base de datos. Olvidaba mencionarle que el archivo index.html dentro de la
carpeta public_html sera la pagina principal del proyecto, en donde crearemos en
front-end del mismo y donde se haran las solicitudes HTTP mediante el uso de la
Librería jQuery o AngularJS. Estén atentos que hare una segunda parte de este
tutorial explicando como consumir un API RestFul desde el cliente con JavaScript.