Crea un servicio web REST con PHP y MYSQL -Parte 2

Creado por jc mouse Miércoles, febrero 24, 2016

Segunda parte del tutorial “Crea un servicio web REST con PHP y MYSQL“, en esta segunda y ultima parte se completara la construcción del REST api implementando el código php para los verbos GET/POST/PUT/DELETE, se realizan a la par los test respectivos con el complemento para Google Chrome Insomnia.

Paso 5. Gestión de Base de Datos

Nuestro sencillo REST api cuenta tan solo con una tabla “people” por lo cual nos daremos el lujo de colocar la conexión a la base de datos y los métodos para gestionarlo en una sola clase, este no es un tutorial sobre base de datos así que no explicaremos nada de eso, la clase se llama “PeopleDB.php” y el código es el siguiente:

<?php
/** 
 * @web http://www.jc-mouse.net/
 * @author jc mouse
 */
class PeopleDB {
    
    protected $mysqli;
    const LOCALHOST = '127.0.0.1';
    const USER = 'root';
    const PASSWORD = '';
    const DATABASE = 'dbTest';
    
    /**
     * Constructor de clase
     */
    public function __construct() {           
        try{
            //conexión a base de datos
            $this->mysqli = new mysqli(self::LOCALHOST, self::USER, self::PASSWORD, self::DATABASE);
        }catch (mysqli_sql_exception $e){
            //Si no se puede realizar la conexión
            http_response_code(500);
            exit;
        }     
    } 
    
    /**
     * obtiene un solo registro dado su ID
     * @param int $id identificador unico de registro
     * @return Array array con los registros obtenidos de la base de datos
     */
    public function getPeople($id=0){      
        $stmt = $this->mysqli->prepare("SELECT * FROM people WHERE id=? ; ");
        $stmt->bind_param('s', $id);
        $stmt->execute();
        $result = $stmt->get_result();        
        $peoples = $result->fetch_all(MYSQLI_ASSOC); 
        $stmt->close();
        return $peoples;              
    }
    
    /**
     * obtiene todos los registros de la tabla "people"
     * @return Array array con los registros obtenidos de la base de datos
     */
    public function getPeoples(){        
        $result = $this->mysqli->query('SELECT * FROM people');          
        $peoples = $result->fetch_all(MYSQLI_ASSOC);          
        $result->close();
        return $peoples; 
    }
    
    /**
     * añade un nuevo registro en la tabla persona
     * @param String $name nombre completo de persona
     * @return bool TRUE|FALSE 
     */
    public function insert($name=''){
        $stmt = $this->mysqli->prepare("INSERT INTO people(name) VALUES (?); ");
        $stmt->bind_param('s', $name);
        $r = $stmt->execute(); 
        $stmt->close();
        return $r;        
    }
    
    /**
     * elimina un registro dado el ID
     * @param int $id Identificador unico de registro
     * @return Bool TRUE|FALSE
     */
    public function delete($id=0) {
        $stmt = $this->mysqli->prepare("DELETE FROM people WHERE id = ? ; ");
        $stmt->bind_param('s', $id);
        $r = $stmt->execute(); 
        $stmt->close();
        return $r;
    }
    
    /**
     * Actualiza registro dado su ID
     * @param int $id Description
     */
    public function update($id, $newName) {
        if($this->checkID($id)){
            $stmt = $this->mysqli->prepare("UPDATE people SET name=? WHERE id = ? ; ");
            $stmt->bind_param('ss', $newName,$id);
            $r = $stmt->execute(); 
            $stmt->close();
            return $r;    
        }
        return false;
    }
    
    /**
     * verifica si un ID existe
     * @param int $id Identificador unico de registro
     * @return Bool TRUE|FALSE
     */
    public function checkID($id){
        $stmt = $this->mysqli->prepare("SELECT * FROM people WHERE ID=?");
        $stmt->bind_param("s", $id);
        if($stmt->execute()){
            $stmt->store_result();    
            if ($stmt->num_rows == 1){                
                return true;
            }
        }        
        return false;
    }
    
}

Paso 6. Códigos de respuesta HTTP

En el código de la clase “PeopleDB” vemos en el constructor de clase que si no se puede conectar a la base de datos, este retorna un código de respuesta HTTP 500 en la linea de código http_response_code(500); (PHP 5 >= 5.4.0, PHP 7) pero ¿y que son estos códigos de respuesta?

Estos códigos son la respuesta que da el servidor web a la solicitud HTTP del cliente y nos brindan información ya sea de éxito o fracaso en la solicitud. Puede ver más información sobre estos códigos en la wiki Códigos de Estado. En resumen se pueden dar 5 tipos de respuesta:

  • 1xx – Informativo
  • 2xx – Éxito
  • 3xx – Redirección
  • 4xx – Error del Cliente
  • 5xx – Error del Servidor

Los códigos de respuesta que utilizaremos en este tutorial son:

  • 500Internal Server Error → Se ha producido un error interno
  • 422Unprocessable Entity → Entidad no procesable
  • 400 : Bad Request → La solicitud contiene sintaxis errónea y no debería repetirse
  • 204 : No Content → La petición se ha completado con éxito pero su respuesta no tiene ningún contenido

Aparte de enviar un código de respuesta HTTP al cliente, puede enviarse también una respuesta en formato JSON y de esta forma ser más detallado con lo sucedido con su solicitud en el servidor. Por ejemplo un mensaje de error pude tener la siguiente forma:Paso 6.1 Respuestas JSON

{

   "status": "error",

   "message": "Uds. No tiene los permisos para modificar este recurso"
    
}

Para realizar esto debemos crear un método en la clase PeopleAPI que ademas de enviar una respuesta HTTP escriba una respuesta con formato JSON, el código del método es:

/**
 * Respuesta al cliente
 * @param int $code Codigo de respuesta HTTP
 * @param String $status indica el estado de la respuesta puede ser "success" o "error"
 * @param String $message Descripcion de lo ocurrido
 */
 function response($code=200, $status="", $message="") {
    http_response_code($code);
    if( !empty($status) && !empty($message) ){
        $response = array("status" => $status ,"message"=>$message);  
        echo json_encode($response,JSON_PRETTY_PRINT);    
    }            
 }   

Paso 7. Consulta GET

Como ya dijimos anteriormente, GET nos permite consultar y leer recursos del Rest api, en este caso, leeremos registros de la única tabla en la base de datos de dos maneras:

  • Obtener un array JSON con todas las personas registradas. URI http://localhost/SampleWS/peoples
  • Obtener persona por ID. URI: http://localhost/SampleWS/peoples/[id]

Cualquier otro tipo de URI sera rechaza con el código de respuesta 400

El nombre de la función se llama getPeoples() y dependiendo si la solicitud cuenta o no con un parámetro ID, se consultara a la base de datos y devolverá en formato JSON el resultado

 1 /**
 2 * función que segun el valor de "action" e "id":
 3 *  - mostrara una array con todos los registros de personas
 4 *  - mostrara un solo registro 
 5 *  - mostrara un array vacio
 6 */
 7 function getPeoples(){
 8     if($_GET['action']=='peoples'){         
 9         $db = new PeopleDB();
10         if(isset($_GET['id'])){//muestra 1 solo registro si es que existiera ID                 
11             $response = $db->getPeople($_GET['id']);                
12             echo json_encode($response,JSON_PRETTY_PRINT);
13         }else{ //muestra todos los registros                   
14             $response = $db->getPeoples();              
15             echo json_encode($response,JSON_PRETTY_PRINT);
16         }
17     }else{
18            $this->response(400);
19     }       
20 }      

implementando el método anterior en la función API(), tenemos

 1 public function API(){
 2     header('Content-Type: application/JSON');                
 3     $method = $_SERVER['REQUEST_METHOD'];
 4     switch ($method) {
 5     case 'GET'://consulta
 6         $this->getPeoples();
 7         break;     
 8     case 'POST'://inserta
 9         echo 'POST';
10         break;                
11     case 'PUT'://actualiza
12         echo 'PUT';            
13         break;      
14     case 'DELETE'://elimina
15         echo 'DELETE';
16         break;
17     default://metodo NO soportado
18         echo 'METODO NO SOPORTADO';
19         break;
20     }
21 }   

El Test 

Guarda los cambios y abre Insomnia, en la primera parte de este tutorial ya habíamos configurado esta aplicación y enseñado a realizar una consulta en 6 sencillos pasos:

1) Selecciona la solicitud: “obtener personas
2) Seleccionar el verbo: GET
3) Escribir la URI: http://localhost/SampleWS/peoples
4) BODY: no tiene
5) Para enviar la solicitud presiona SEND
6) Respuesta: La respuesta del servidor se mostrara en formato JSON

get api

1) Selecciona la solicitud: “persona por ID

2) Seleccionar el verbo: GET
3) Escribir la URI: http://localhost/SampleWS/peoples/2
4) BODY: no tiene
5) Para enviar la solicitud presiona SEND
6) Respuesta: La respuesta del servidor se mostrara en formato JSON

get people

Paso 6. POST

El verbo POST permite insertar un nuevo objeto a la base de datos, dicho objeto sera enviado en formato JSON, en el servidor se decodifica el objeto y si no corresponde retorna un error 422, si el objeto si es un JSON pero no tiene las etiquetas necesarias o estas están mal escritas, también retorna error 422, caso contrario realizara el registro y retornara una respuesta de éxito en formato JSON.

 1 /**
 2  * metodo para guardar un nuevo registro de persona en la base de datos
 3  */
 4 function savePeople(){
 5     if($_GET['action']=='peoples'){   
 6         //Decodifica un string de JSON
 7         $obj = json_decode( file_get_contents('php://input') );   
 8         $objArr = (array)$obj;
 9         if (empty($objArr)){
10             $this->response(422,"error","Nothing to add. Check json");                           
11         }else if(isset($obj->name)){
12             $people = new PeopleDB();     
13             $people->insert( $obj->name );
14             $this->response(200,"success","new record added");                             
15         }else{
16             $this->response(422,"error","The property is not defined");
17         }
18     } else{               
19         $this->response(400);
20     }  
21 }

Agregamos el método savePeople() a la clase e implementamos este en el método API:

 1     public function API(){
 2         header('Content-Type: application/JSON');                
 3         $method = $_SERVER['REQUEST_METHOD'];
 4         switch ($method) {
 5         case 'GET'://consulta
 6             $this->getPeoples();
 7             break;     
 8         case 'POST'://inserta
 9             $this->savePeople();
10             break;                
11         case 'PUT'://actualiza
12             echo 'PUT';            
13             break;      
14         case 'DELETE'://elimina
15             echo 'DELETE';
16             break;
17         default://metodo NO soportado
18             echo 'METODO NO SOPORTADO';
19             break;
20         }
21     }

El test

1) Selecciona la solicitud: “nueva persona
2) Seleccionar el verbo: POST
3) Escribir la URI: http://localhost/SampleWS/peoples
4) BODY: objeto JSON

{
    "name":"jc mouse"
}

5) Para enviar la solicitud presiona SEND
6) Respuesta: La respuesta del servidor se mostrara en formato JSON

restapi record

A continuación la respuesta del API cuando el JSON tiene etiquetas incorrectas:

http code

Paso 7. PUT

PUT nos sirve para actualizar un recurso pasado como objeto JSON y al igual que en el método savePeople(), este método updatePeople() validar la información que se le pase y actuara en consecuencia

/**
 * Actualiza un recurso
 */
function updatePeople() {
    if( isset($_GET['action']) && isset($_GET['id']) ){
        if($_GET['action']=='peoples'){
            $obj = json_decode( file_get_contents('php://input') );   
            $objArr = (array)$obj;
            if (empty($objArr)){                        
                $this->response(422,"error","Nothing to add. Check json");                        
            }else if(isset($obj->name)){
                $db = new PeopleDB();
                $db->update($_GET['id'], $obj->name);
                $this->response(200,"success","Record updated");                             
            }else{
                $this->response(422,"error","The property is not defined");                        
            }     
            exit;
       }
    }
    $this->response(400);
}

Agregamos este método a la clase e implementando en el método API:

    public function API(){
        header('Content-Type: application/JSON');                
        $method = $_SERVER['REQUEST_METHOD'];
        switch ($method) {
        case 'GET'://consulta
            $this->getPeoples();
            break;     
        case 'POST'://inserta
            $this->savePeople();
            break;                
        case 'PUT'://actualiza
            $this->updatePeople();
            break;      
        case 'DELETE'://elimina
            echo 'DELETE';
            break;
        default://metodo NO soportado
            echo 'METODO NO SOPORTADO';
            break;
        }
    }

El test

1) Selecciona la solicitud: “actualizar registro”
2) Seleccionar el verbo: PUT
3) Escribir la URI: http://localhost/SampleWS/peoples/3 (el registro añadido con POST)
4) BODY: objeto JSON

{
    "name":"Aquiles brinco"
}

5) Para enviar la solicitud presiona SEND
6) Respuesta: La respuesta del servidor se mostrara en formato JSON

update rest

y provocamos un error mandando en el body un poco de basura

REST API

Paso 8. DELETE

Para terminar implementamos el verbo DELETE que como indica su nombre nos sirve para eliminar un recurso, Como respuesta HTTP se usa el código 204 y no el código 200.

    /**
     * elimina persona
     */
    function deletePeople(){
        if( isset($_GET['action']) && isset($_GET['id']) ){
            if($_GET['action']=='peoples'){                   
                $db = new PeopleDB();
                $db->delete($_GET['id']);
                $this->response(204);                   
                exit;
            }
        }
        $this->response(400);
    }

Agregamos el método a la clase e implementamos en el método API:

    public function API(){
        header('Content-Type: application/JSON');                
        $method = $_SERVER['REQUEST_METHOD'];
        switch ($method) {
        case 'GET'://consulta
            $this->getPeoples();
            break;     
        case 'POST'://inserta
            $this->savePeople();
            break;                
        case 'PUT'://actualiza
            $this->updatePeople();
            break;      
        case 'DELETE'://elimina
            $this->deletePeople();
            break;
        default://metodo NO soportado
            $this->response(405);
            break;
        }
    }

Test

1) Selecciona la solicitud: “eliminar registro
2) Seleccionar el verbo: DELETE
3) Escribir la URI: http://localhost/SampleWS/peoples/3
4) BODY: no tiene
5) Para enviar la solicitud presiona SEND
6) Respuesta: La respuesta del servidor corresponde al código 204 “No Content”

apirest delete

Hasta aquí terminamos de construir nuestro sencillo REST api en php y MySQL, el código no es grande y claro que le falta la seguridad/Autenticación pero eso lo veremos en otra ocasión.

enjoy!!!

Si te ha gustado podrías compartirlo o dejar un comentario. ¡Muchas gracias!

Sobre el autor y el sitio web

Yo soy yo :) Mouse o como algunos de ustedes me llaman 'El Cochinote', Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.

Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye

Enjoy! :)

ENTRADAS QUE TE PUEDEN INTERESAR

13 comentarios en “Crea un servicio web REST con PHP y MYSQL -Parte 2”

  1. Muy buenos tutoriales, solo una duda me salia error al importar la clase PeopleDB
    le puse require_once(‘PeopleDB.php’); al inicio de PeopleAPI y se me soluciono el problema, si encontraron otra la solucion me comentan por favor.

    1. Mouse dice:

      gracias por el aviso revisare que paso, tal vez se me olvido colocarlo 🙂

  2. Carlos M Gómez dice:

    Muchas gracias por todos tus aportes, sos la onda!

  3. franklin dice:

    La salida es de esta forma.
    algún detalle en el código? para que salga como se muestra en el ejemplo?


    <!–

    [
    {
    “id”: “1”,
    “name”: “juan”
    },
    {
    “id”: “2”,
    “name”: “manuel”
    }
    ]

    –>

  4. Cristhoper dice:

    Muchas gracias por el tutorial, claro y limpio.

  5. Humberto dice:

    Una pregunta ya que veo que no funciona lo que quiero hacer.
    Si yo quisiera ingresar dos registros en el metodo POST me dice que hay un error de parametros, el json que paso tiene la estructura siguiente:
    [{
    “nombre”:”JOSE”,
    “apellido”:”CAMPO”
    },
    {
    “nombre”:”MARIA”,
    “apellido”:”CAMPO”
    }]

    como hago para que me guarde esos dos registros?

  6. Jeysson Gonzalez dice:

    Saludos!
    Tengo una duda por que en tu Método ‘API()’ preguntas por el tipo de request ya sea POST,GET y otros, y despues en las otras funciones como ‘savePeople()’ utilizas siempre GET y no POST que seria la correspondiente a agregar una nueva persona… espero haberme dado a entender

    1. Mouse dice:

      uuuuu revisare el código 🙂 ando volando en otros lenguajes 🙂

  7. Jair dice:

    Muchas gracias, muy buen tutorial

    Espero me pueda ayudar con una duda

    Quise hacer un ejemplo de un sitio y utilizar este ejemplo, para consultas e inserción utilice Ajax y funciono muy bien, pero ya no pude editar.

  8. eder mario dice:

    buenas noches

    disculpa, me gustaria saber donde copio el Paso 7. Consulta GET en la funcion getPeoples(), es que nose en donde debo copiarla, gracias

  9. Dajan MEdina dice:

    hERMANO mOUSE TENGO ESTE PEQUEÑO PROBLEMA

    Fatal error: Call to a member function query() on null in C:\xampp\htdocs\SampleWS\PeopleDB.php on line 45

  10. potter dice:

    Buenas resulta que he hecho todo como tu pero me he quedado atascado en el momento que haces lo del “get” resulta que cuando lo quiero consultar con el “insomnia” me da este error, “Fatal error: Class ‘PeopleDB’ not found in C:\xampp\htdocs\SampleWS\PeopleAPI.php on line 61

    Si me pudieras echar una mano te lo agradecería de corazón!

  11. JOSE LUIS dice:

    Incluye todas las funciones dentro de class PeopleAPI {….}

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *


*

Comparte lo que sabes

Categorias

Android Bolivia

Bandera en Alto

Ultimas entradas

En este oportunidad comparto una pequeña aplicación hecha en java para recortar partes de una imagen seleccionado con el...

En este post crearemos un componente que solo hay en android y que no esta disponible en la paleta de controles de Netbe...

Radio.Garden es un proyecto interactivo desarrollado por el Instituto Holandés para el Sonido y la Visión en cooperación...

Una cola doblemente terminada o deque es una estructura de datos lineal que permite insertar y eliminar elementos por am...

Web amigas