Creación de una API RESTful con Laravel

 

Creación de una API RESTful con Laravel

En este tutorial, te guiaré paso a paso para crear una API RESTful básica con Laravel, incluyendo autenticación, rutas, controladores y migraciones.

Requisitos previos

  • PHP ≥ 8.1

  • Composer instalado

  • Laravel instalado globalmente

  • Conocimientos básicos de PHP y Laravel

  • Base de datos configurada (MySQL, PostgreSQL, SQLite, etc.)

Paso 1: Crear un nuevo proyecto Laravel

bash
laravel nuevo mi-api-laravel
# O usando composer
composer create-project laravel/laravel mi-api-laravel

Accede al directorio del proyecto:

bash
cd mi-api-laravel

Paso 2: Configurar la base de datos

Abre el archivo .env y configura las credenciales de tu base de datos:

env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mi_api_laravel
DB_USERNAME=root
DB_PASSWORD=

Paso 3: Crear un modelo con migración, controlador y factory

Vamos a crear un modelo Producto como ejemplo:

bash
php artisan make:model Producto -mcr

Esto creará:

  • Un modelo (app/Models/Producto.php)

  • Una migración (database/migrations/..._create_productos_table.php)

  • Un controlador (app/Http/Controllers/ProductoController.php)

Paso 4: Definir la migración

Abre el archivo de migración creado y define la estructura de la tabla:

php
public function up()
{
    Schema::create('productos', function (Blueprint $table) {
        $table->id();
        $table->string('nombre');
        $table->text('descripcion')->nullable();
        $table->decimal('precio', 8, 2);
        $table->integer('stock');
        $table->timestamps();
    });
}

Ejecuta las migraciones:

bash
php artisan migrate

Paso 5: Configurar el modelo Producto

Abre app/Models/Producto.php y define los campos asignables masivamente:

php
protected $fillable = [
    'nombre', 
    'descripcion', 
    'precio', 
    'stock'
];

Paso 6: Crear el controlador de la API

Modifica app/Http/Controllers/ProductoController.php para implementar los métodos CRUD:

php
<?php

namespace App\Http\Controllers;

use App\Models\Producto;
use Illuminate\Http\Request;

class ProductoController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        return response()->json(Producto::all(), 200);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'nombre' => 'required|string|max:255',
            'descripcion' => 'nullable|string',
            'precio' => 'required|numeric|min:0',
            'stock' => 'required|integer|min:0'
        ]);

        $producto = Producto::create($validated);
        return response()->json($producto, 201);
    }

    /**
     * Display the specified resource.
     */
    public function show(Producto $producto)
    {
        return response()->json($producto, 200);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, Producto $producto)
    {
        $validated = $request->validate([
            'nombre' => 'sometimes|string|max:255',
            'descripcion' => 'nullable|string',
            'precio' => 'sometimes|numeric|min:0',
            'stock' => 'sometimes|integer|min:0'
        ]);

        $producto->update($validated);
        return response()->json($producto, 200);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Producto $producto)
    {
        $producto->delete();
        return response()->json(null, 204);
    }
}

Paso 7: Definir las rutas de la API

Abre routes/api.php y define las rutas para tu API:

php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductoController;

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

// Rutas para Productos
Route::apiResource('productos', ProductoController::class);

// Si necesitas rutas específicas
Route::get('/productos/buscar/{nombre}', [ProductoController::class, 'buscarPorNombre']);

Paso 8: Instalar y configurar Sanctum para autenticación API

Laravel Sanctum proporciona un sistema de autenticación simple para APIs:

bash
composer require laravel/sanctum

Publica los archivos de configuración y migraciones:

bash
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"

Ejecuta las migraciones:

bash
php artisan migrate

Paso 9: Crear sistema de autenticación

Genera el controlador de autenticación:

bash
php artisan make:controller AuthController

Edita app/Http/Controllers/AuthController.php:

php
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:8|confirmed',
        ]);

        $user = User::create([
            'name' => $validated['name'],
            'email' => $validated['email'],
            'password' => Hash::make($validated['password']),
        ]);

        $token = $user->createToken('api-token')->plainTextToken;

        return response()->json([
            'user' => $user,
            'token' => $token
        ], 201);
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        $user = User::where('email', $request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            throw ValidationException::withMessages([
                'email' => ['Las credenciales proporcionadas son incorrectas.'],
            ]);
        }

        $token = $user->createToken('api-token')->plainTextToken;

        return response()->json([
            'token' => $token
        ]);
    }

    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();

        return response()->json(['message' => 'Sesión cerrada correctamente']);
    }
}

Paso 10: Añadir rutas de autenticación

En routes/api.php, añade:

php
use App\Http\Controllers\AuthController;

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->post('/logout', [AuthController::class, 'logout']);

// Proteger las rutas de productos
Route::middleware('auth:sanctum')->apiResource('productos', ProductoController::class);

Paso 11: Probar la API

Puedes probar tu API con Postman, cURL o cualquier cliente HTTP. Aquí hay algunos ejemplos:

Registrar un usuario

text
POST http://localhost:8000/api/register
Content-Type: application/json

{
    "name": "Usuario Ejemplo",
    "email": "usuario@ejemplo.com",
    "password": "password123",
    "password_confirmation": "password123"
}

Iniciar sesión

text
POST http://localhost:8000/api/login
Content-Type: application/json

{
    "email": "usuario@ejemplo.com",
    "password": "password123"
}

Crear un producto (necesita autenticación)

text
POST http://localhost:8000/api/productos
Content-Type: application/json
Authorization: Bearer [tu-token-de-autenticación]

{
    "nombre": "Producto de ejemplo",
    "descripcion": "Este es un producto de prueba",
    "precio": 99.99,
    "stock": 100
}

Obtener todos los productos

text
GET http://localhost:8000/api/productos
Authorization: Bearer [tu-token-de-autenticación]

Paso 12: Mejoras adicionales (opcional)

  1. Paginación:

    php
    public function index()
    {
        return response()->json(Producto::paginate(10), 200);
    }
  2. Transformadores de datos:
    Usa Laravel Resources para formatear las respuestas:

    bash
    php artisan make:resource ProductoResource
  3. Validación avanzada:
    Crea Form Requests para validaciones complejas:

    bash
    php artisan make:request StoreProductoRequest
  4. Documentación:
    Usa herramientas como Swagger o Scribe para documentar tu API.

  5. CORS:
    Configura CORS en config/cors.php para permitir solicitudes desde tu frontend.

Conclusión

Ahora tienes una API RESTful básica con Laravel que incluye:

  • Autenticación con Sanctum

  • Operaciones CRUD para productos

  • Validación de datos

  • Rutas protegidas

Puedes expandir esta API añadiendo más modelos, relaciones, endpoints adicionales y cualquier otra funcionalidad que necesites.

Recuerda que para un entorno de producción deberías considerar:

  • Uso de HTTPS

  • Validaciones más robustas

  • Manejo de errores detallado

  • Limitación de peticiones (rate limiting)

  • Pruebas automatizadas

  • Monitoreo del API

Comentarios

Entradas más populares de este blog

crear controladores separados para API y Web

Laravel tanto para web como para API al mismo tiempo.

Creación de una API RESTful con Laravel (sin autenticación)