Crear un API Rest en Laravel

En este artículo vamos a aprender a crear una API REST con Laravel, es decir, una aplicación que nos permita trabajar con una base de datos y después poder consumirla mediante cualquier otro lenguaje o un framework fronted de terceros, esos datos.

Domina la Creación de API REST en Laravel: Guía Exhaustiva con las mejores practicas de desarrollo [Actualizado a 2024]

Como crear una APIRest con Laravel

En este artículo, exploraremos qué es una API Rest y cómo puedes crear una utilizando Laravel, uno de los principales y más modernos framework de PHP, y con gran demanda en el mercado. Las API Rest se han convertido en un estándar de facto para la comunicación entre el servidor y el cliente en aplicaciones web modernas, ofreciendo una forma flexible y eficiente de manejar las solicitudes HTTP.

Al construir un API con Laravel, un popular framework de PHP para desarrollo web, se aprovechan sus capacidades robustas y su arquitectura elegante para facilitar el desarrollo de APIs RESTful de alta calidad.

¿Qué es una API REST?

Un API REST (Interfaz de Programación de Aplicaciones de Transferencia de Estado Representacional) es un conjunto de definiciones y protocolos que se utiliza para desarrollar e integrar el software de las aplicaciones.

Permite a diferentes sistemas de software comunicarse entre sí a través de internet de manera simple y estandarizada, utilizando los métodos HTTP (GET, POST, PUT, DELETE, entre otros) para realizar operaciones CRUD (Crear, Leer, Actualizar, Eliminar) sobre los recursos, que son representados generalmente en formatos JSON o XML.

Importancia de las APIs REST

Las APIs son cruciales para la reutilización de funcionalidades en el desarrollo de software, permitiendo sistemas más robustos y escalables sin necesidad de compartir el código subyacente.

Creación de una API REST con Laravel

Configuración Inicial y Herramientas Necesarias

Para empezar con Laravel y crear tu API REST, necesitarás:

  • Entorno de desarrollo: XAMPP o MAMP.
  • Composer: Para manejar las dependencias de PHP.
  • Postman: Para probar tu API.

Iniciar el proyecto para crear un API REST con Laravel

Inicia tu proyecto ejecutando:

composer create-project laravel/laravel apirestfull

Este comando configura la estructura base de Laravel, incluyendo el archivo .env para la configuración de la base de datos.

Configuración del Modelo Book

Crea el modelo Book junto con su controlador, migración y factory con el siguiente comando:

cd apirestfull
php artisan make:model Book -cmf

¿Qué significa el parámetro -cmf? En el momento de crear nuestro archivo para el modelo, también vamos a crear los archivos Controller, Migration, y Factory. Un poco más adelante explicaremos para que sirven cada uno de estos archivos.

Comenzaremos configurado nuestro modelo Book:

class Book extends Model
{
  use HasFactory;

  protected $fillable = [
    'title','description'
  ];

  public function tags(): BelongsToMany
  {
    return $this->belongsToMany(Tag::class);
  }
  public function category(): BelongsTo
  {
    return $this->belongsTo(Category::class);
  }
  public function user(): BelongsTo
  {
    return $this->belongsTo(User::class);
  }
}

Configuración de Migraciones y Seeders

Añadimos nuestros atributos fillable, la relación con el modelo User que ya viene creado por defecto en Laravel, además de una función para transformar el atributo descripción cuando accedamos a él. Lo que realizaremos es mostrar un máximo de 120 caracteres.

Configuramos la migración del modelo Book con sus campos y su relación con el modelo User.

public function up(): void
{
        Schema::create('books', function (Blueprint $table) {
           $table->id();
           $table->unsignedBigInteger('user_id');
           $table->string('title');
           $table->longText('description');

           $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

           $table->timestamps();
        });
}

Y por último, configuramos el Factory de Book, para crear registros falsos que usaremos para realizar nuestras pruebas.

El Factory de usuario ya viene creado por defecto con la instalación del proyecto,  solo debemos crear el de books.

class BookFactory extends Factory
{
  public function definition(): array
  {
    return [
     'user_id' => User::all()->random()->id,
     'title' => $this->faker->sentence(),
     'description' => $this->faker->text(), 
   ];
  }
}

A continuación configuramos el Seeders para lanzar los Factories cuando ejecutemos las migraciones. Crearemos 10 usuarios y 50 libros:

class DatabaseSeeder extends Seeder
{

   public function run(): void
   {
     \App\Models\User::factory()->create(['email' => 'i@admin.com']);
     \App\Models\User::factory(29)->create();

     \App\Models\Book::factory(30)->create();
   }
}

Antes de ejecutar las migraciones, debemos tener nuestra base de datos creada y el archivo .env configurado hacía esa BD.

Generamos las migraciones con todos los datos de prueba que hemos configurado, ejecutando el comando:

php artisan migrate --seed

Desarrollo de la API, creación de controladores, con sus recursos y rutas

Controladores

Crea un controlador específico para tu API, donde --api genera métodos CRUD y --model=Book lo asocia con el modelo Book:

php artisan make:controller  Api/V1/BookController --api --model=Book

Ficheros Request

Los archivos Request en Laravel son clases especiales que encapsulan toda la lógica de validación de los datos de entrada de una aplicación. Estos archivos son una parte esencial de la arquitectura de Laravel y se utilizan para organizar y manejar la validación de manera eficiente y segura, separando así las preocupaciones de validación del resto del código de la aplicación, como los controladores.

Para crear un archivo Request en Laravel, se puede utilizar el comando artisan make:request

Esto generará una nueva clase Request en el directorio app/Http/Requests

class CreateBookRequest extends FormRequest
{

   public function authorize(): bool
   {
     return true;
   }

   public function rules(): array
   {
     return [
       'title' => 'required',
       'description' => 'required',
     ];
   }
}

Resources y Respuestas JSON

Los archivos “Resources” en Laravel representan una forma elegante y conveniente de transformar modelos y colecciones de datos en un formato JSON específico para su salida a través de una API. Estos archivos son parte de lo que Laravel denomina “Eloquent Resources”, que permiten personalizar la respuesta JSON que tu aplicación envía al cliente, controlando exactamente qué datos se incluyen y cómo se formatean

Para crear un archivo Request en Laravel, se puede utilizar el comando artisan make:resource

Esto generará una nueva clase Request en el directorio app/Http/Resources

php artisan make:resource  V1/BookResource
php artisan make:resource  V1/BookCollection

Configuración Archivos Resource y Controller

Pasemos a las configuraciones de estos archivos que hemos creado. Controlador, para este ejemplo vamos a usar únicamente tres métodos, index, store, show y destroy.

class BookController extends Controller
{
    public function index(): JsonResponse
    {
      $books = Auth::user()->books()->with('category', 'tags', 'user')->get();

      return response()->json(['data' => BookResource::collection($books)]);
    }

    public function store(CreateBookRequest $request): JsonResponse
    {
      $book = $request->user()->books()->create($request->all());

      $book->save();
      return response()->json(new BookResource($book), Response::HTTP_CREATED);
    }

    public function show(Book $book): JsonResponse
    {
        $this->authorize('show', $book);

        $book =$book->load('user');
        return response()->json(new BookResource($book));
    }


    public function destroy(Book $book): JsonResponse
    {
       $this->authorize('delete', $book);

       $book->delete();

       return response()->json(null, Response::HTTP_NO_CONTENT);
    }

}

Como puedes comprobar, en el método index, store y show, llamamos a nuestro recurso BookResource y BookResource::collection. Para ello debemos llamar a la clase, tal y como aparece en la primera línea de la imagen.

En el archivo BookResource,  únicamente añadiremos está información:

public function toArray(Request $request): array
{
   return [
      'id' => $this->id,
      'type' => 'book',
      'attributes' => [
           'title' => $this->title,
           'description' => $this->description,
       ]
  ];
}

En el archivo BookCollection,  únicamente añadiremos está información:

public function toArray(Request $request): array
{
      return $this->collection->map(function ($book) {
          return [
             'id' => $book->id,
             'type' => 'book',
             'attributes' => [
                 'title' => $book->name,
                 'description' => $book->description,
             ]
          ];
      })->toArray();

}

Ahora pasaremos a configurar nuestro archivo de rutas. Para eso iremos al fichero routes\api.php

Importaremos nuestro controlador al principio del fichero,  le daremos un Alias (esto último no es necesario) y debajo definiremos nuestras rutas:

use App\Http\Controllers\Api\V1\BookController as BookV1;

Route::apiResource('v1/books', BookV1::class)
      ->only(['index', 'store', 'show', 'destroy'])
      ->middleware('auth:sanctum');

Lo que hemos realizado es definir todas las rutas con “apiResource”, pero especificamos que de momento solo vamos tener activas las rutas index, show y destroy con el atributo “only”. Por último agregamos el middleware de autentificación con la librería Sanctum. Con esto protegeremos el acceso a las rutas de nuestra API, convirtiéndola en una API privada.

Autenticación con Laravel Sanctum

Instalar Laravel Sanctum

Laravel Sanctum proporciona un sistema de autenticación para SPA (aplicaciones de una sola página), aplicaciones móviles y API simples basadas en tokens. Sanctum permite que cada usuario de su aplicación genere múltiples tokens API para su cuenta. A estos tokens se les pueden otorgar habilidades / alcances que especifican qué acciones pueden realizar los tokens.

Controlador Login

Ahora crearemos un controlador que gestione el acceso y autenticación de nuestra API. Se va a crear en la ruta de la API, pero fuera de la versión.

php artisan make:controller Api/LoginController
php artisan make:request Api/LoginRequest

Avancemos en nuestras configuraciones. En routes\api.php, generamos la ruta Login.

Route::post('login', [App\Http\Controllers\Api\LoginController::class, 'login']);

Ahora accedemos a LoginController y agregamos el siguiente código:

class LoginController extends Controller
{
      public function login(LoginRequest $request): JsonResponse
      {
        $user = User::where('email', $request->email)->first();

        if (! $user || ! Hash::check($request->password, $user->password)) {
           return response()->json([
             'message' => 'The provided credentials are incorrect.'
           ], Response::HTTP_UNPROCESSABLE_ENTITY);

        }

        return response()->json([
               'data' => [
               'attributes'=> [
                   'id' => $user->id,
                   'name' => $user->name,
                   'email' => $user->email
                ],
               'token' => $user->createToken($request->device_name)->plainTextToken
             ],
            ], Response::HTTP_OK);
      }

}

Ahora accedemos a LoginRequest y agregamos el siguiente código:

class LoginRequest extends FormRequest
{

  public function authorize(): bool
  {
    return true;
  }


  public function rules(): array
  {
     return [
        'email' => 'required|email',
        'password' => 'required',
        'device_name' => 'required',
     ];
  }
}

Policies

Los archivos “Policies” en Laravel son clases que definen reglas de autorización para las acciones que los usuarios pueden realizar en los recursos de tu aplicación. Estas políticas de acceso ayudan a mantener la lógica de autorización organizada y separada del resto de tu código, facilitando su mantenimiento y comprensión. Laravel utiliza estas políticas principalmente para controlar el acceso a los modelos Eloquent, permitiendo definir de manera clara y conveniente quién puede crear, ver, actualizar o eliminar recursos.

Para crear una policy en Laravel, puedes utilizar el comando Artisan make:policy

Laravel generará automáticamente una clase de policy en el directorio app/Policies

Esta clase contendrá métodos que representan las diferentes acciones que los usuarios pueden intentar realizar sobre el modelo asociado. Por ejemplo, una policy para un modelo Post podría incluir métodos como view(), create(), update(), y delete().

En nuestro caso quedaría así:

class BookPolicy
{
   public function update(User $user, Book $book): bool
   {
     return $user->id === $book->user_id;
   }

   public function delete(User $user, Book $book): bool
   {
     return $user->id === $book->user_id;
   }

   public function show(User $user, Book $book): bool
   {
     return $user->id === $book->user_id;
    }

}

Pruebas desde Postman

Ahora sí, ya hemos terminado toda la configuración y nuestra API ya está creada. Vamos a ponerla a prueba desde Postman !

 Postman es una aplicación que nos permite realizar pruebas API. Es un cliente HTTP que nos da la posibilidad de testear ‘HTTP requests’ a través de una interfaz gráfica de usuario, por medio de la cual obtendremos diferentes tipos de respuesta que posteriormente deberán ser validados

Lo primero que tendremos que hacer es autentificarnos para obtener el token que nos permitan acceder a la API. Para eso, nos autentificaremos usaremos el método POST con email y contraseña de un usuario existente en nuestra base de datos. Para obtener ese usuario,  accede a la tabla de usuarios y copia el email de cualquiera de los registros que creamos al principio, y la clave que usaras será “password”. Laravel por defecto, pone como contraseña “password”, a todos los usuarios que crea como datos de prueba.

La petición debería quedar así:

Una vez realizada la petición y si todo ha ido bien, nos devolverá una respuesta con el token generado y el mensaje  Success. Tal y como lo configuramos.

Ya nos hemos autentificado en nuestra pequeña aplicación, Enhorabuena. Ahora probemos a realizar alguna consulta a nuestra API.

Copia el token generado e  inclúyelo en el apartado de Authorization.

Para eso vamos a Postman, cambiamos el método a GET y  añadimos la url que hemos definido en las rutas para obtener un libro. En Authorization, vamos a Type y seleccionamos “Bearer Token”,  y en el campo Token, pegamos el código generado en el paso anterior, así:

En la pestaña de  body marcamos none, y lanzamos la consulta

El resultado que nos muestra es la información del libro con Id 1. En este caso el titulo y descripción, que es la información que le configuramos en el fichero BookResource. Fácil verdad?

Si quisiéramos obtener todos los libros, la consulta sería al endpoint

GET http://localhost:8000/api/v1/books/

Por último, para probar la tercera ruta que tenemos configurada, que es la de eliminar un recurso, le pasaríamos el id del recurso que queremos eliminar, al siguiente endpoint:

DELETE http://localhost:8000/api/v1/books/1

Has creado con éxito una API REST utilizando Laravel, desde la configuración inicial hasta la autenticación y pruebas. Este tutorial es un primer paso hacia el desarrollo avanzado de APIs REST con Laravel. Para profundizar, experimenta con diferentes tipos de autenticación, explora más sobre los recursos y considera implementar pruebas automatizadas.

¿Interesado en explorar más o tienes preguntas? No dudes en contactarme o deja un comentario abajo. ¡Sigamos aprendiendo juntos!

Fuentes:

RedhatItalo Morales


Suscríbete a nuestra Newsletter

Mantente al día con nuestras últimas novedades y accede a recursos gratuitos exclusivos.
* indicates required

4 comentarios

    • Hola Javier, me alegro de que te guste el contendio del blog.
      A tú pregunta si se puede implementar hexagonal en Laravel, sí es posible. Requiere de ciertas configuraciones, pero no es complicado integrar esta arquitectura.
      Un saludo

  1. La guía está bastante bien, pero carece de utilidad real. No lo tomes a mal, pero publicar código de Laravel sin calificar las clases completamente no sirve de nada.
    Me explico: en Laravel, una referencia a una clase Response tiene 5 ó 6 posibilidades. No incluir el path completo a la clase o el “use” correspondiente inutilizan el tutorial.
    Un saludo.

    • Hola Camelia,
      Agradezco tus comentarios y tienes toda la razón, en otras entradas si se incluye todo el código de la clase o enlace al repo. En este caso al actualizar la información, elimine esas referencias al código de un repo bastante antiguo.
      Lo tomo en cuenta, para actualizar la entrada y para las próximas.
      Un saludo

Deja un comentario

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