NOTAS WEB
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]
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:
Desarrollador de software con más de 7 años de experiencia, especializado en desarrollo web y backend. Con habilidades demostradas en PHP, Laravel, Symfony, y una amplia gama de tecnologías modernas. Apasionado por el diseño y desarrollo de software.
Enhorabuena por el post. Pero tengo una duda, seria posible mplementar hexagonal con Laravel. Gracias
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
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