Curso de Laravel

Estructura de un proyecto de Laravel: qué hay en cada carpeta

Por Víctor Peña · Publicado el

Hola, ¿cómo están? Continuando con el curso de Laravel, hoy recorremos la estructura del proyecto que creamos en la lección anterior.

Abrir un proyecto de Laravel por primera vez impresiona: hay muchas carpetas y no está claro dónde escribir. Al terminar esta lección vas a saber exactamente qué es cada cosa.

¡Empecemos!

La estructura de un proyecto nuevo

sistema-clinica/
├── app/
├── bootstrap/
├── config/
├── database/
├── public/
├── resources/
├── routes/
├── storage/
├── tests/
├── vendor/
├── .env
├── artisan
└── composer.json

Vamos una por una, y al final resumimos dónde vas a trabajar de verdad.

app: aquí vive tu código

Es la carpeta más importante. Contiene la lógica de tu aplicación, con el espacio de nombres App y cargada automáticamente por Composer mediante PSR-4.

En un proyecto recién creado solo contiene tres subcarpetas:

app/
├── Http/
│   └── Controllers/
├── Models/
└── Providers/

Y aquí hay algo que sorprende a quien viene de versiones anteriores del framework: eso es todo lo que hay.

Las demás carpetas —Jobs, Events, Listeners, Mail, Policies, Rules, Consoleno existen hasta que las necesitas. Se crean solas cuando ejecutas el comando correspondiente:

php artisan make:job ProcesarPedido      # crea app/Jobs/
php artisan make:mail ConfirmacionCita   # crea app/Mail/
php artisan make:policy CitaPolicy       # crea app/Policies/

Es un cambio deliberado: en lugar de darte veinte carpetas vacías, aparecen cuando tienen contenido.

Http

Todo lo relacionado con recibir peticiones: controladores, middleware y form requests.

Si vienes de tutoriales antiguos, notarás que ya no existe app/Http/Kernel.php. El middleware ahora se configura en otro sitio, que vemos enseguida.

Models

Los modelos de Eloquent. Cada tabla de tu base de datos tendrá su clase aquí.

Providers

Los proveedores de servicios, que arrancan la aplicación. En un proyecto nuevo solo está AppServiceProvider, y es donde registrarás configuraciones globales cuando lo necesites.

bootstrap: el arranque del framework

Contiene app.php, y este archivo es importante porque concentra la configuración que antes estaba repartida en varios kernels:

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        // aquí se registra el middleware
    })
    ->withExceptions(function (Exceptions $exceptions) {
        // aquí se maneja el reporte de errores
    })->create();

Si buscas dónde registrar un middleware o cómo cambiar el manejo de excepciones, es aquí. Los antiguos app/Http/Kernel.php, app/Console/Kernel.php y app/Exceptions/Handler.php desaparecieron y su función vive en este archivo.

También hay una carpeta bootstrap/cache con archivos generados por el framework. No la toques.

config: la configuración

Archivos PHP que devuelven arreglos con las opciones de cada componente: base de datos, correo, caché, sesiones, sistema de archivos.

// config/app.php
'name' => env('APP_NAME', 'Laravel'),
'timezone' => 'UTC',

Fíjate en el patrón: los valores se leen del .env con un valor por defecto. La configuración vive aquí; los valores concretos, en el .env.

Para leerla desde tu código:

config('app.name')
config('database.default')

Un consejo: dale una lectura a estos archivos aunque no cambies nada. Están comentados y es la mejor forma de descubrir qué se puede configurar.

database: la estructura de los datos

database/
├── factories/     ← generadores de datos de prueba
├── migrations/    ← el control de versiones de tu base de datos
└── seeders/       ← datos iniciales

Las migraciones son de lo mejor que tiene Laravel: en vez de crear tablas a mano en phpMyAdmin, se definen en código que se versiona con Git. Así todo el equipo tiene la misma estructura.

Las veremos a fondo en el módulo de base de datos.

public: lo único visible desde internet

Contiene index.php, que es el punto de entrada de todas las peticiones, y los archivos accesibles públicamente: imágenes, CSS y JavaScript compilados.

Esto es un detalle de seguridad importante: el servidor debe apuntar a public, no a la raíz del proyecto. Si apunta a la raíz, cualquiera podría acceder a tu .env escribiendo la dirección.

resources: el frontend sin compilar

resources/
├── css/
├── js/
└── views/     ← las plantillas Blade

views es donde vas a pasar bastante tiempo: ahí van los archivos .blade.php que generan el HTML.

Los archivos de css y js son el código fuente; el resultado compilado termina en public/build.

routes: qué responde a cada dirección

En un proyecto nuevo hay dos archivos:

routes/
├── web.php       ← rutas del navegador
└── console.php   ← comandos y tareas programadas

web.php es donde defines las direcciones de tu aplicación:

Route::get('/pacientes', [PacienteController::class, 'index']);

Y aquí otra cosa que confunde a quien sigue tutoriales antiguos: api.php no viene por defecto. Si vas a construir una API, se instala con:

php artisan install:api

Lo mismo con los canales de broadcasting:

php artisan install:broadcasting

Es coherente con la idea del resto: nada que no uses.

storage: lo que genera la aplicación

storage/
├── app/          ← archivos de tu aplicación
├── framework/    ← caché, sesiones, vistas compiladas
└── logs/         ← los registros de error

storage/logs/laravel.log es el primer sitio donde mirar cuando algo falla. Acostúmbrate a abrirlo.

Y si tu aplicación guarda archivos subidos por usuarios —fotos de perfil, documentos— van en storage/app/public, con un enlace simbólico para hacerlos accesibles:

php artisan storage:link

Esta carpeta necesita permisos de escritura. En Linux o macOS es la causa habitual del error 500 tras un despliegue.

tests: las pruebas automatizadas

Vienen configuradas de fábrica, con Pest o PHPUnit según lo que hayas elegido al crear el proyecto.

php artisan test

vendor: no la toques

Las dependencias instaladas por Composer. No se edita y no se sube al repositorio: se reconstruye con composer install.

Dónde vas a trabajar realmente

Con todo lo anterior claro, este es el mapa práctico:

Quieres… Vas a…
Definir una dirección routes/web.php
Escribir la lógica de una pantalla app/Http/Controllers/
Consultar la base de datos app/Models/
Diseñar lo que se ve resources/views/
Cambiar la estructura de las tablas database/migrations/
Cambiar credenciales o configuración .env
Ver por qué falló algo storage/logs/laravel.log

Esas siete rutas son el 95 % de tu trabajo diario. El resto de carpetas existen, pero las vas a abrir muy de vez en cuando.

Ver las carpetas que puedes generar

Para descubrir qué más puede crear el framework:

php artisan list make

Devuelve la lista completa de generadores. Cada uno crea su carpeta si no existe.

Errores comunes

  • Apuntar el servidor a la raíz del proyecto en lugar de a public. Es un problema de seguridad serio.
  • Buscar app/Http/Kernel.php siguiendo un tutorial antiguo. Ya no existe: mira bootstrap/app.php.
  • Esperar que routes/api.php esté ahí. Hay que instalarlo.
  • Editar algo en vendor. Se pierde en la próxima instalación.
  • Subir .env o vendor al repositorio.
  • No mirar el log cuando algo falla, y depurar a ciegas.

Para cerrar

La estructura de Laravel parece grande al principio, pero la mayor parte son carpetas que el framework usa por dentro. Tu código vive en cuatro sitios: rutas, controladores, modelos y vistas.

Y quédate con la idea de fondo del diseño actual: lo que no usas, no existe. Las carpetas aparecen cuando el comando correspondiente las necesita.

En la siguiente lección vemos Artisan, que es la herramienta que genera casi todo lo que hemos mencionado.

Saludos y éxitos.

Norvic Software

Desarrollamos el software que tu empresa necesita

Somos una fábrica de software en Bolivia. Construimos sistemas a medida y aplicaciones móviles, y llevamos Inteligencia Artificial a las empresas que ya tienen un sistema funcionando.

Solicitar cotizaciónVer todos los servicios

Cotización sin costo · Respuesta directa por WhatsApp