Secciones

Entradas del blog


REST API en CodeIgniter 4

Sin comentarios

Introducción

REST API es una implementación de la API (Application Programming Interface) y por otro lado REST por sus siglas en inglés (REpresentational State Transfer) es una arquitectura de método de comunicación que utiliza el protocolo HTTP para el intercambio de datos y este método se aplica a menudo en el desarrollo de aplicaciones.

Puede parecer complicado, pero no lo es, sólo hay que ser un poco atentos y leer bien lo que prosigue.

El objetivo es hacer un sistema con buen rendimiento, rápido y fácil de desarrollar, especialmente en el intercambio de datos y la comunicación.

¿Por qué usar un REST API?


Si se observa la arquitectura tradicional de comunicación de datos entre el cliente y el servidor se parece a la siguiente imagen:

Donde el cliente envía una solicitud al servidor a través de HTTP Request, y el servidor proporciona una respuesta a través de HTTP Response.

La respuesta la da el servidor, normalmente en formato HTML. Sin embargo, Imagina que tienes que desarrollar tu sitio web en una aplicación móvil como Android o iOS. Y se sabe que tanto las aplicaciones de Android como de iOS no necesitan HTML como respuesta del servidor, porque Android e iOS utilizan diferentes lenguajes de programación y no reconocen HTML. Por lo tanto, tenemos que crear una API RESTful.

De tal forma, que RESTful API será un puente de comunicación de datos entre el cliente y el servidor. Así, el servidor ya no envía HTML como respuesta, sino sólo datos.

Sí, así es, sólo datos.

Esta respuesta en forma de datos se puede utilizar para varias plataformas de aplicaciones con diferentes lenguajes de programación. La respuesta de la API suele estar en formato JSON o XML. Sin embargo, el más utilizado es JSON.

En este tutorial, se creará una API REST con datos de respuesta en formato JSON.

Mira la siguiente imagen para entender mejor la arquitectura de la API REST:

Donde los clientes pueden ser de varias plataformas, como aplicaciones web, de escritorio o móviles. Eso suena más factible, correcto?

Paso 1. Diseñar la API REST

Antes de crear una API REST, es una buena idea definir el EndPoint de la API REST que se va a crear. El EndPoint son las rutas de la API que vamos a crear.

API REST utilizando verbs HTTP. Los verbos HTTP más utilizados son GET, POST, PUT y DELETE.

GET para obtener datos del servidor o más conocido como READ, POST para CREAR nuevos datos, PUT para UPDATE (actualizar) datos, y DELETE para eliminar datos.

O mejor conocido como CRUD (Create-Read-Update-Delete).

En este tutorial, compartir cómo crear una sencilla API REST para recuperar datos del servidor (GET), crear nuevos datos al servidor (POST), actualizar datos al servidor (PUT), y borrar datos al servidor (DELETE) de una tabla de la base de datos, concretamente la tabla "product".

A continuación se muestra el diseño de la API REST que vamos a crear:

Paso 2. Crear una base de datos y una tabla

Crear una nueva base de datos con MySQL, puedes utilizar herramientas como PHPMyAdmin u otras similares. En este ejemplo, se usó phpMyAdmin con DBeaver como cliente

Crear la base de datos con el nombre de "restful_db" o el nombre que consideren necesario.

Para crear una base de datos con MySQL, se puede hacer ejecutando la siguiente consulta:

CREATE DATABASE restful_db;

Crear la tabla "product" con la siguiente instrucción:

CREATE TABLE product(
	product_id INT(11) PRIMARY KEY AUTO_INCREMENT,
	product_name VARCHAR(200),
	product_price DOUBLE
)ENGINE=INNODB;

Insertar datos de pruebas:

INSERT INTO product(product_name,product_price) VALUES
('Product 1','2000'),
('Product 2','5000'),
('Product 3','4000'),
('Product 4','6000'),
('Product 5','7000');

Paso #3. Instalación de CodeIgniter 4

Éste tutorial utilizó las siguientes características y software:

  • Fedora 35 x86_64
  • XAMPP 8.1.1
  • Codeigniter 4.1.6
  • MariaDB
  • DBeaver
  • Postman

Crear proyecto CodeIgniter 4 desde composer, con la siguiente línea:

composer create-project codeigniter4/appstarter restfulapi

Éste proyecto se creará en la ruta de su servidor PHP, en éste ejemplo, se usó XAMPP 8.1.1. Pero pueden usar cualquier otro servidor de prueba, como WAMPP, LAMPP ó AMPP

cd restfulapi

Paso 4. Conectar con la base de datos

Abrir el archivo "Database.php" ubicado en la carpeta "app/Config", luego encuentre el siguiente código:

public $default = [
        'DSN'      => '',
        'hostname' => 'localhost',
        'username' => '',
        'password' => '',
        'database' => '',
        'DBDriver' => 'MySQLi',
        'DBPrefix' => '',
        'pConnect' => false,
        'DBDebug'  => (ENVIRONMENT !== 'production'),
        'charset'  => 'utf8',
        'DBCollat' => 'utf8_general_ci',
        'swapPre'  => '',
        'encrypt'  => false,
        'compress' => false,
        'strictOn' => false,
        'failover' => [],
        'port'     => 3306,
];

Modificar los accesos respectivamente, con los datos de conexión

public $default = [
    'DSN'      => '',
    'hostname' => 'localhost',
    'username' => 'root',
    'password' => '',
    'database' => 'restful_db',
    'DBDriver' => 'MySQLi',
    'DBPrefix' => '',
    'pConnect' => false,
    'DBDebug'  => (ENVIRONMENT !== 'production'),
    'cacheOn'  => false,
    'cacheDir' => '',
    'charset'  => 'utf8',
    'DBCollat' => 'utf8_general_ci',
    'swapPre'  => '',
    'encrypt'  => false,
    'compress' => false,
    'strictOn' => false,
    'failover' => [],
    'port'     => 3306,
];

Si por alguna razón, hay problemas en la conexión con el siguiente mensaje de error:

CodeIgniter\Database\Exceptions\DatabaseException #8
Unable to connect database : Codeigniter

Si se obtiene ese error Codeigniter - no puede conectarse a la base de datos MySQL, entonces se debe cambiar el valor del nombre de host basado en el servidor local que se esté usando, por ejemplo MAMPP o XAMPP.

# MAMPP
public $default = [
  ...
     'hostname' => '/Applications/MAMP/tmp/mysql/mysql.sock',
  ...
]

# XAMPP
public $default = [
  ...
     'hostname' => '/Applications/XAMPP/xamppfiles/var/mysql/mysql.sock',
  ...
]

Para que se tenga una buena interfaz para manejar los errores, encontrar el archivo env en la raíz del proyecto, renómbralo a .env y ábrelo.

Luego encuentra el siguiente código:

CI_ENVIRONMENT = development

Esto significa que entra en el modo de desarrollo, este modo le ayudará a hacer más fácil el seguimiento de los errores a medida que construye su proyecto.

Paso #5. Crear un archivo de modelo

Crear un archivo modelo llamado "ProductModel.php" en la carpeta "app/Models", y luego escriba el siguiente código:

<?php
namespace App\Models;

use CodeIgniter\Model;

class ProductModel extends Model
{
    protected $table = 'product';
    protected $primaryKey = 'product_id';
    protected $allowedFields = ['product_name','product_price'];
}

Paso 6. Crear un archivo controlador

Crear un archivo controlador llamado "Products.php" en la carpeta "app/Controllers", luego escriba el siguiente código:

<?php
namespace App\Controllers;
 
use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;
use App\Models\ProductModel;

class Products extends ResourceController
{
    use ResponseTrait;
    // get all product
    public function index()
    {
        $model = new ProductModel();
        $data = $model->findAll();
        return $this->respond($data, 200);
    }
 
    // get single product
    public function show($id = null)
    {
        $model = new ProductModel();
        $data = $model->getWhere(['product_id' => $id])->getResult();
        if($data){
            return $this->respond($data);
        }else{
            return $this->failNotFound('No Data Found with id '.$id);
        }
    }
 
    // create a product
    public function create()
    {
        $model = new ProductModel();
        $data = [
            'product_name' => $this->request->getPost('product_name'),
            'product_price' => $this->request->getPost('product_price')
        ];
        $model->insert($data);
        $response = [
            'status'   => 201,
            'error'    => null,
            'messages' => [
                'success' => 'Data Saved'
            ]
        ];
         
        return $this->respondCreated($data, 201);
    }
 
    // update product
    public function update($id = null)
    {
        $model = new ProductModel();
        $json = $this->request->getJSON();
        if($json){
            $data = [
                'product_name' => $json->product_name,
                'product_price' => $json->product_price
            ];
        }else{
            $input = $this->request->getRawInput();
            $data = [
                'product_name' => $input['product_name'],
                'product_price' => $input['product_price']
            ];
        }
        // Insert to Database
        $model->update($id, $data);
        $response = [
            'status'   => 200,
            'error'    => null,
            'messages' => [
                'success' => 'Data Updated'
            ]
        ];
        return $this->respond($response);
    }

    // delete product
    public function delete($id = null)
    {
        $model = new ProductModel();
        $data = $model->find($id);
        if($data){
            $model->delete($id);
            $response = [
                'status'   => 200,
                'error'    => null,
                'messages' => [
                    'success' => 'Data Deleted'
                ]
            ];
            return $this->respondDeleted($response);
        }else{
            return $this->failNotFound('No Data Found with id '.$id);
        }    
    }
}

CodeIgniter 4 ha facilitado a los desarrolladores web la creación de API REST.

Se puede ver en el controlador "Products.php" de arriba, con sólo extender "ResourceController" podemos crear una "API REST".

Y no sólo eso, también podemos crear fácilmente respuestas utilizando el "API ResponseTrait".

Paso #7. Configuración de Routes.php

El último paso que no es menos importante es hacer una pequeña configuración en el archivo "Routes.php" ubicado en la carpeta "app/Config".

Abrir el archivo "Routes.php" en la carpeta "app/Config", luego encuentre el siguiente código:

$routes->get('/', 'Home::index');

Cambiarlo a ésta línea:

$routes->resource('productos');

Esta configuración permite acceder al siguiente EndPoint:

Paso 8. Habilitar CORS (Cross-Origin Resources Sharing)


Esto es importante. Para que se pueda acceder a los recursos fuera del dominio, es necesario habilitar CORS. Para habilitar CORS, crear un archivo llamado "Cors.php" en la carpeta "app/Filters".

Luego agregar el siguiente código:

<?php
namespace App\Filters;

use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;

Class Cors implements FilterInterface
{
    public function before(RequestInterface $request, $arguments = null)
    {
        header('Access-Control-Allow-Origin: *');
        header("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method, Authorization");
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
        $method = $_SERVER['REQUEST_METHOD'];
        if ($method == "OPTIONS") {
            die();
        }
    }
 
    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
      // Do something here
    }
}

Abrir el archivo "Filters.php" en la carpeta "app/Config". A continuación, buscar el siguiente código:

public $aliases = [
    'csrf'     => \CodeIgniter\Filters\CSRF::class,
    'toolbar'  => \CodeIgniter\Filters\DebugToolbar::class,
    'honeypot' => \CodeIgniter\Filters\Honeypot::class,
];

A continuación, añadir un filtro "cors" de la siguiente manera:

public $aliases = [
   'csrf'     => \CodeIgniter\Filters\CSRF::class,
   'toolbar'  => \CodeIgniter\Filters\DebugToolbar::class,
   'honeypot' => \CodeIgniter\Filters\Honeypot::class,
   'cors'     => \App\Filters\Cors::class, 
];

A continuación, definir "cors" en $globals público como sigue:

public $globals = [
    'before' => [
        'cors'
        //'honeypot'
        // 'csrf',
    ],
    'after'  => [
        'toolbar',
        //'honeypot'
    ],
];

Paso 9. Probar el proyecto


Para probar la API que se ha creado, hay muchas herramientas que se pueden utilizar. En este tutorial, se usó POSTMAN.

Descargar POSTMAN en el sitio web oficial:

https://www.getpostman.com/

Instalar postman puede ser mediante el paquete de descarga y ejecutarlo, o bien, desde la tienda de software de Fedora

El proyecto se puede descargar de aquí, en caso de querer descargarlo:

https://github.com/jesusferm/Codeigniter4-REST-API

Paso 10. Ejecución

Para iniciar el proyecto, ejecutar el siguiente comando:

php spark serve

1. Obtener todos los productos (GET)

Abrir POSTMAN, y escribir la siguiente URL en el campo URL de Postman:

http://localhost:8080/products

Seleccionar el método GET, luego clic en el botón Send, entonces los resultados aparecerán como se muestra a continuación:

Si al ejecutar la sentencia, los datos se recuperan, entonces todo va bien.

2.- Obtener un solo producto (GET)

Escribir la siguiente URL en la columna URL para obtener un solo producto:

http://localhost:8080/products/12

Seleccionar el método GET, luego haga clic en el botón Send, entonces los resultados aparecerán como se muestra a continuación:

Si con el id 12 no hay datos, corregir a uno que sí esté registrado en la base de datos

3. Crear un nuevo producto (POST)

Escribir la siguiente URL en la columna URL para crear un nuevo producto:

http://localhost:8080/products

Seleccionar el método POST => Body => form-urlencoded => Introduzca KEY y VALUE => clic en Send.

Como la siguiente imagen:

Si se obtiene una respuesta con el estado 201 como se muestra arriba, los datos se han almacenado con éxito en la base de datos.

4. Actualizar producto (PUT)

Escribir la siguiente URL en la columna URL para actualizar el producto:

http://localhost:8080/products/12

Seleccionar el método PUT => Body => form-urlencoded => Introduzca KEY y VALUE => clic en Send.

Como la siguiente imagen:

Si se obtiene una respuesta de estado 200 como se muestra arriba, los datos se han actualizado con éxito en la base de datos según el id de producto actualizado.

5. Eliminar un producto (DELETE)

Escribir la siguiente URL en el campo URL para eliminar el producto:

http://localhost:8080/products/13

Seleccionar el método DELETE y clic en Enviar.

Como en la siguiente imagen:

Si obtiene una respuesta de estado 200 como se muestra arriba, los datos se han eliminado con éxito en la base de datos.

Conclusión

Aquí finaliza la codificación y ahora, a probarlo, pueden descargar el proyecto de github, sin problema alguno.

Fuentes:

Comentarios:

Entradas del blog
Redes sociales
Accesos directos