Blog de Robert Torres
Instalar Backend API REST con Laravel Lumen
Proceso de instalacion paso a paso de un backend sencillo de una sola tabla de base de datos usando PHP framework Laravel Lumen version 10:
Requisito previo obviamente en para este tutorial, tener Linux + Apache Server + PHP > 8.0 y Mysql server o Postgresql.
Ademas, Laravel Lumen requiere que tengas instaladas de las siguentes extensiones de PHP:
- OpenSSL PHP
- PDO PHP
- Mbstring
- ZIP (opcional)
- XML (opcional)
- curl (vamos a probar conexiones con php-curl)
Tambien debes tener instalado composer (es un manejador de dependencias de PHP)
Paso 1:
Instalar Laravel Lumen de la siguiente forma:
En la consola de Linux ejecutamos composer de la siguiente manera:
composer create-project --prefer-dist laravel/lumen api-test
Paso 2
Generar una App Key para nuestro backend, para esto ejecutamos en la consola de Linux lo siguiente:
php -r "echo bin2hex(random_bytes(32));"
Esto devuelve como resultado algo como esto:
54e2adb7d8eed9619e700f04aef3fde231d917d17ebc5867224d7a74fcb8f929
Paso 3
Editamos el archivo .env que se encuentra en el directorio raiz de la aplicacion en nuestro caso, la aplicacion quedo instalada en la carpeta llamada api-test por lo tanto el .env debe estar ubicado en api-test/.env.
Editaremos la linea con la variable APP_KEY y en ella pegamos el string que generamos en el Paso 2
Ademas en este paso, aprovechamos de agregar los parametros asociados a la base de datos DB_DATABASE, DB_USERNAME, DB_PASSWORD y DB_CONNECTION (mysql en este caso).
El .env por el momento, deberia quedar asi:
APP_NAME=Lumen
APP_ENV=local
APP_KEY=54e2adb7d8eed9619e700f04aef3fde231d917d17ebc5867224d7a74fcb8f929
APP_DEBUG=true
APP_URL=http://localhost
APP_TIMEZONE=UTC
LOG_CHANNEL=stack
LOG_SLACK_WEBHOOK_URL=
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=apitest
DB_USERNAME=tunombredeusuario
DB_PASSWORD=tupassword
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
Destacamos el parametro DB_DATABASE al que le asignamos el valor de apitest, debido a que mas adelante, debemos crear una base de datos en mysql con ese mismo nombre.
Paso 4
Editamos el archivo que esta en la carpeta bootstrap/app.php por ahora solo descomentamos las siguientes lineas:
$app->withFacades();
$app->withEloquent();
Paso 5
Creamos la migracion para la tabla opiniones, para ello, desde la consola de linux ejecutamos la siguiente linea:
php artisan make:migration create_opiniones_table
El resultado devuelto debe ser algo como esto:
INFO Migration [/home/robetorr/api-test/database/migrations/2023_08_17_205246_create_opiniones_table.php] created successfully.
Paso 6
Editar 2023_08_17_205246_create_opiniones_table.php (archivo generado en el paso 5) que se encuentra ubicado en la carpeta database/migrations de la aplicacion y agregar los siguientes campos:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('opiniones', function (Blueprint $table) {
$table->bigIncrements();
$table->text('nombre');
$table->text('email');
$table->text('mensaje');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('opiniones');
}
};
Paso 7 MySql
Entramos a mysql
mysql -u robetorr -p
Creamos la base de datos
create database apitest;
Salimos de mysql (ctrl+d)
Paso 6
Ejecutar la migracion. En la raiz de la aplicacion ejecutar:
php artisan migrate
Si todo esta bien y los parametros del .env coinciden con los de tu base de datos, esto debe devolver lo siguiente:
INFO Preparing database.
Creating migration table ............................................................................................. 916ms DONE
INFO Running migrations.
2023_08_17_205246_create_opiniones_table ........................................................................... 1,206ms DONE
Has creado la tabla opiniones en la base de datos apitest.
Paso 7
Creamos el modelo en la carpeta app/Model y lo llamaremos app/Model/Opinion.php debe quedar asi:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Opinion extends Model
{
protected $fillable = ['nombre', 'email','mensaje'];
}
Paso 8
Creamos el controlador en app/Http/Controllers/ y lo llamaremos app/Controllers/OpinionController.php y creamos los metodos index,show,store,update y destroy. El arcivo deberia quedar de esta manera:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Opinion;
class OpinionController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
//
}
public function index(){
try
{
$Opiniones = Opinion::all();
}
catch (Exception $e)
{
return response()->json([
'responseCode' => '500',
'response' => 'Internal Server Error',
'data' => [
'errorCode' => 'Error-1',
//"exception" => $e->getMessage(),
'errorMessage' => 'Error getting Opinions'
]
], 500);
}
if($Opiniones)
{
$data = [];
foreach($Opiniones as $Opinion)
{
$types = [];
$types = [
'id' => $Opinion->id,
'nombre' => $Opinion->nombre,
'email' => $Opinion->email,
'id_post' => $Opinion->id_post,
'mensaje' => $Opinion->mensaje
];
$data[] = $types;
}
}
if($data)
{
return response()->json([
'responseCode' => 200,
'response' => 'OK',
'data' => $data
], 200);
}
else
{
return response()->json([
'responseCode' => 404,
'response' => 'Not Found',
'data' => [
'errorCode' => 'Error-2',
'errorMessage' => 'Opinions was not found'
]
], 404);
}
}
public function show($id){
try
{
$Opinion = Opinion::where('id', $id)->first();
}
catch (Exception $e)
{
return response()->json([
'responseCode' => '500',
'response' => 'Internal Server Error',
'data' => [
'errorCode' => 'Error-1',
//"exception" => $e->getMessage(),
'errorMessage' => 'Error getting Opinions'
]
], 500);
}
if($Opinion)
{
$data = [];
$data = [
'id' => $Opinion->id,
'nombre' => $Opinion->nombre,
'email' => $Opinion->email,
'id_post' => $Opinion->id_post,
'mensaje' => $Opinion->mensaje
];
}
if($data)
{
return response()->json([
'responseCode' => 200,
'response' => 'OK',
'data' => $data
], 200);
}
else
{
return response()->json([
'responseCode' => 404,
'response' => 'Not Found',
'data' => [
'errorCode' => 'Error-2',
'errorMessage' => 'Opinion was not found'
]
], 404);
}
}
public function store(Request $request){
$data = new Opinion();
if($request->input('nombre')){
$data->nombre = $request->input('nombre');
}else{
return response()->json([
'responseCode' => '422',
'response' => 'Validation Error',
'data' => [
'errorCode' => '001',
'error' => 'Nombre no puede estar vacio'
]
], 422);
}
if($request->input('email')){
$data->email = $request->input('email');
}else{
return response()->json([
'responseCode' => '422',
'response' => 'Validation Error',
'data' => [
'errorCode' => '002',
'error' => 'Email no puede estar vacio'
]
], 422);
}
if($request->input('mensaje')){
$data->mensaje = $request->input('mensaje');
}else{
return response()->json([
'responseCode' => '422',
'response' => 'Validation Error',
'data' => [
'errorCode' => '003',
'error' => 'mensaje no puede estar vacio'
]
], 422);
}
try
{
$data->save();
return response()->json(['responseCode' => 200, 'response' => 'OK', 'data' => $data], 200);
}
catch (Exception $e)
{
return response()->json([
'responseCode' => '500',
'response' => 'Internal Server Error',
'data' => [
'errorCode' => 'Error-1',
//"exception" => $e->getMessage(),
'errorMessage' => 'Error storing Opinions'
]
], 500);
}
}
public function update($id, Request $request){
try
{
$data = Opinion::where('id',$id)->first();
}
catch (Exception $e)
{
return response()->json([
'responseCode' => '500',
'response' => 'Internal Server Error',
'data' => [
'errorCode' => 'Error-1',
//"exception" => $e->getMessage(),
'errorMessage' => 'Error getting Opinions'
]
], 500);
}
if($request->input('nombre')){
$data->nombre = $request->input('nombre');
}else{
return response()->json([
'responseCode' => '422',
'response' => 'Validation Error',
'data' => [
'errorCode' => '001',
'error' => 'Nombre no puede estar vacio'
]
], 422);
}
if($request->input('email')){
$data->email = $request->input('email');
}else{
return response()->json([
'responseCode' => '422',
'response' => 'Validation Error',
'data' => [
'errorCode' => '002',
'error' => 'Email no puede estar vacio'
]
], 422);
}
if($request->input('mensaje')){
$data->mensaje = $request->input('mensaje');
}else{
return response()->json([
'responseCode' => '422',
'response' => 'Validation Error',
'data' => [
'errorCode' => '003',
'error' => 'mensaje no puede estar vacio'
]
], 422);
}
try
{
$data->save();
return response()->json(['responseCode' => 200, 'response' => 'OK', 'data' => $data], 200);
}
catch (Exception $e)
{
return response()->json([
'responseCode' => '500',
'response' => 'Internal Server Error',
'data' => [
'errorCode' => 'Error-1',
//"exception" => $e->getMessage(),
'errorMessage' => 'Error updating Opinions'
]
], 500);
}
}
public function destroy($id){
try
{
$data = Opinion::where('id',$id)->first();
}
catch (Exception $e)
{
return response()->json([
'responseCode' => '500',
'response' => 'Internal Server Error',
'data' => [
'errorCode' => 'Error-1',
//"exception" => $e->getMessage(),
'errorMessage' => 'Error getting Opinion'
]
], 500);
}
try
{
$data->delete();
return response()->json(['responseCode' => 200, 'response' => 'OK', 'data' => $data], 200);
}
catch (Exception $e)
{
return response()->json([
'responseCode' => '500',
'response' => 'Internal Server Error',
'data' => [
'errorCode' => 'Error-1',
//"exception" => $e->getMessage(),
'errorMessage' => 'Error deleting Opinion'
]
], 500);
}
}
}
Paso 9
Editamos el archivo routes/web.php y agregamos las rutas de la siguiente manera:
<?php
/** @var \Laravel\Lumen\Routing\Router $router */
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/
$router->get('/', function () use ($router) {
return $router->app->version();
});
$router->group(['prefix' => 'api'], function () use ($router) {
$router->get('opinion/all', ['uses' => 'OpinionController@index']);
$router->get('opinion/{id}', ['uses' => 'OpinionController@show']);
$router->post('opinion', ['uses' => 'OpinionController@store']);
$router->put('opinion/{id}', ['uses' => 'OpinionController@update']);
$router->delete('opinion/{id}', ['uses' => 'OpinionController@destroy']);
}