En publicaciones anteriores logramos armar un set de herramientas que nos permite con mas facilidad y usabilidad crear el proceso de petición y respuesta en un server(cliente-servidor), así como también el procesamiento de rutas y parámetros, que en si es lo principal o lo mas usado en un proyecto web. Hasta este momento no hemos usado ningún framework, solo paquetes, como por ejemplo en el caso de el archivo de configuración y el sistema de plantillas con Twig.

En esta publicación empezaremos a configurar nuestro backend para poder hacer peticiones desde el frontend por medio de un api. Entendemos como backend en groso modo como la columna vertebral de nuestra aplicación, en otra caso de uso sería un componente del patrón de diseño MVC(Model View Controller) y en conjunto con el Model se completaría el backend en este patrón de diseño.

Modelando nuestros datos.

Como comentamos en capítulos anteriores nos vamos a basar en la estructura de datos básica de un Pokemon, y después iremos actualizando y agregando mas features a nuestra app. Por el momento nuestra estructura quedaría de esta forma:

id(bigint): Identificador único en nuestra tabla, por aquello del álgebra relacional y normalización de base de datos.

image(text): Imagen del Pokemon. String de la imagen codificada en base64.

code(string, length:6): Código del Pokemon en el Pokedex. Ej: 006 = Charizard

name(string, length:200): Nombre del Pokemon. Ej: Charizard

description(string, length:256): Descripción del Pokemon. Ej: Escupe un fuego tan caliente que funde las rocas. Causa incendios forestales sin querer.

height(decimal): Altura del Pokemon en metros.

weight(decimal): Peso del Pokemon en metros.

ability(string, length:256): Habilidad del Pokemon.

Una vez ya definida nuestra estructura de datos, crearemos nuestra base de datos con su tabla. En este tema no daré mayor detalle sobre la creación de tablas y base de datos en SQL. Simplemente el motor de base de datos sera en MySQL.

Podemos usar cualquier IDE para administrar base de datos para la creación de la misma. Por ejemplo yo uso el administrador de base de datos de PHPStorm. Otro IDE muy usado seria MySQL Workbench.

Conectando al servidor de Base de Datos con el PHP Storm.
Creación de una tabla con PHP Storm.
Nuestra base de datos y tabla creadas.

Configurando nuestra conexión para que se comunique con Eloquent.

Previamente ya habíamos instalado el paquete Eloquent vía Composer, entonces empezaremos a configurarlo y usarlo.

Creamos la carpeta config y el archivo db.php:

Copiar código:mkdir config && touch db.php && cd config

Editamos el archivo db.php con lo siguiente:

Copiar código:<?php
use Illuminate\Database\Capsule\Manager as Capsule;

$capsule = new Capsule;
$capsule->addConnection([
'driver' => env_var('DB_DRIVER', 'mysql'),
'host' => env_var('DB_HOST', 'localhost'),
'database' => env_var('DB_DATABASE', 'database'),
'username' => env_var('DB_USER', 'root'),
'password' => env_var('DB_PASSWORD', 'password'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
]);
$capsule->bootEloquent();

Se acuerdan del helper para el archivo de configuración, aquí lo usamos para obtener la configuración de la base de datos de ese archivo. En el archivo .env agregamos lo siguiente:

Copiar código:DB_DRIVER=mysql
DB_HOST=mysql #Modificar
DB_DATABASE=pokedex
DB_USER=root #Modificar
DB_PASSWORD=root #Modificar

Creando nuestro Modelo.

Como sabremos Eloquent se maneja por clases que en este contexto llamaremos Modelo(con esto cubrimos la M en el patrón de diseño MVC). Por cada tabla que se tenga en la base de datos se tendrá que agregar una clase con el nombre en singular y dentro de esta clase la configuración a la tabla, cabe mencionar que se puede dejar vacía la clase pero nos tendremos que asegurar que nuestra tabla en la base de datos cumpla con los valores por default que tiene Eloquent para el modelo.

Creamos nuestro modelo:

Copiar código:mkdir app/Models && cd app/Models && touch Pokemon.php

Editamos nuestro modelo con lo siguiente:

Copiar código:<?php


namespace App\Models;

require "config/db.php";

use Illuminate\Database\Eloquent\Model;

class Pokemon extends Model
{
protected $table = 'pokemons';
}

En esta clase incluiremos la configuración(config/db.php) y después configuramos dentro de la clase la propiedad de “$table”; esta propiedad indica el nombre de la tabla a la cual queremos relacionar el modelo.

Probando nuestro modelo.

Para probar nuestro modelo, creamos un registro en la tabla para poder consultarlo por el modelo.

Después simplemente creamos una ruta y hacemos la petición.

Copiar código:$route->add('/api', function () {
$data = \App\Models\Pokemon::all()->toArray();

response()->json($data, 201);
});

Ejecutamos el método all() del modelo, este nos traerá todos los registros, después convertimos el array de collection que regresa el modelo a array(metodo encadenado toArray()) y lo pasamos como parámetro al metodo json() del helper response().

Deberíamos de ver algo parecido:

Creando un Comando para llenar nuestra base de datos.

Para automatizar el llenado de nuestra base de datos y no hacer este proceso manualmente, construiremos un comando el cual se conectará al api pública de los Pokemon(https://pokeapi.co/) e insertará todos esos datos en nuestra tabla. Esto se usa mucho para tener datos y hacer pruebas cuando uno programa ciertos módulos y revisar el comportamiento. Nos conectaremos al api pública vía CURL y después llenaremos nuestra tabla de “pokemons” con la respuesta del api.

Creamos el código del comando:

Copiar código:cd app && mkdir Commands && cd Commands && touch DbSeedCommand.php

Codificamos el comando:

Copiar código:<?php


namespace App\Commands;

use App\Models\Pokemon;

class DbSeedCommand
{
public function run()
{
echo "------ Pokedex Database Seed Command ------\n";
$apiUrl = "https://pokeapi.co/api/v2/pokemon?limit=150&offset=0";
$pokemonArr = [];

echo "Consultando: {$apiUrl}\n";
$apiConn = \curl_init($apiUrl);
\curl_setopt($apiConn, CURLOPT_RETURNTRANSFER, true);
$apiResponse = json_decode(curl_exec($apiConn), true);
\curl_close($apiConn);

echo "Agregando Pokemons a memoria temporal .";
foreach ($apiResponse['results'] as $response) {
$outpuCommandMsgTimeStatus = '.';

echo $outpuCommandMsgTimeStatus;

$pokemonApiConn = \curl_init($response['url']);
\curl_setopt($pokemonApiConn, CURLOPT_RETURNTRANSFER, true);
$pokemonData = json_decode(curl_exec($pokemonApiConn), true);
\curl_close($pokemonApiConn);

array_push($pokemonArr, [
'code' => str_pad((string)$pokemonData['id'], 3, "0", STR_PAD_LEFT),
'name' => ucwords($pokemonData['name']),
'image' => $pokemonData['sprites']['other']['official-artwork']['front_default'],
'height' => (string)$pokemonData['height'],
'weight' => (string)$pokemonData['weight'],
'ability' => ucwords($pokemonData['abilities'][0]['ability']['name']),
]);
}

echo "\nInsertando pokemons en la base de datos.\n";
Pokemon::insert($pokemonArr);

echo "Pokemons insertados con exito!\n";
}
}

Nos conectaremos al api de Pokemons vía “curl”, después procesaremos la respuesta que nos devuelva ese api y al último insertaremos ese array de pokemons con el método “insert” del modelo.

En raíz de nuestro proyecto creamos nuestro archivo shell, el cual va ejecutar la clase DbSeedCommand.php:

Copiar código:touch db-seed

Y lo codificamos:

Copiar código:#!/usr/bin/php
<?php


if (php_sapi_name() !== 'cli') {
exit;
}
require __DIR__ . '/vendor/autoload.php';

use App\Commands\DbSeedCommand;

$seedCommand = new DbSeedCommand();
$seedCommand->run();

La línea que contiene “ #!/usr/bin/php” le indica al archivo que va ser ejecutado por php en consola. Después incluye el “autoload” para poder incluir la clase DbSeedCommand y ejecutarla.

Le damos permisos de ejecución:

Copiar código:chmod +x db-seed

Ejecutamos el comando:

Copiar código:./db-seed

Deberíamos de ver algo así en nuestra consola:

Para probar que realmente se insertaron los datos ejecutamos nuestra ruta api creada en pasos anteriores y deberíamos de tener mas de un registro:

Con el comando ya podemos llenar nuestra base de datos con registros reales, ya que esta api toma toda la información que debe tener un Pokemon, aunque aquí la adaptamos a nuestra estructura de datos de la tabla.

También con esto probamos el model y la ejecución de queries con Eloquent. Si quieres saber mas de Eloquent puedes leer su documentación en este link: https://laravel.com/docs/8.x/eloquent

Pueden consultar el código de esta publicación en este repositorio: https://github.com/krsrk/pokedex-vanilla-php

Si les gusto la publicación denle claps, likes y comentarios.

La siguiente publicación esta lista, en ella crearemos un controller y lo refactorizaremos con el patrón repository, lo puedes ver aquí:

https://link.medium.com/xMtDbP4KIab

--

--

Chris Lopez
Chris Lopez

Written by Chris Lopez

Laravel, PHP, Python, Js, Vue Developer

No responses yet