> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Registro y alcance del middleware de paquetes

> A partir de la implementación del Router de Laravel 13, explica cómo registrar alias de middleware de un paquete, aplicarlos de forma explícita, evitar sobrescribir grupos y verificar el comportamiento con la caché.

Cuando añades funcionalidad HTTP a un paquete, separa el hecho de que el middleware esté disponible del hecho de aplicarlo a las peticiones de la aplicación que lo usa. Si diseñas el paquete para que la simple instalación no cambie el comportamiento de todas las rutas, resulta más fácil controlar el impacto de su adopción y la compatibilidad futura.

Esta página parte de los [fundamentos del desarrollo de paquetes](/es/advanced/package-development) y toma como referencia la documentación oficial de Laravel `13.x` y la implementación de Framework `v13.36.0`. Para saber cómo escribir un middleware normal, consulta [Middleware](/es/middleware).

## Separar registro, aplicación y ejecución

`Router::aliasMiddleware()` registra en un array del Router el alias como clave y el nombre de la clase como valor. No crea instancias del middleware ni lo aplica a ninguna ruta.

```mermaid theme={null}
flowchart TD
    A["boot del proveedor"] --> B["Registrar nombre y clase<br>con aliasMiddleware"]
    C["Definición de rutas"] --> D["Indicar el nombre que se aplica<br>con middleware"]
    B --> E["Se determina la ruta de la petición"]
    D --> E
    E --> F["Expandir alias y grupos<br>Aplicar exclusiones y prioridad"]
    F --> G["Pipeline ejecuta el middleware"]
```

| Operación | Función | Lo que no hace por sí sola |
| - | - | - |
| `aliasMiddleware()` | Registra la correspondencia entre un nombre y una clase | Aplicarlo a las peticiones |
| `middleware()` de la ruta | Lo asigna a la ruta de destino | Implementar la clase del middleware |
| `middlewareGroup()` | Define el contenido de un grupo con nombre | Añadirlo al middleware global |
| Añadirlo a la pila global del HTTP Kernel | Lo aplica a todas las peticiones | Permitir exclusiones por ruta |

El nombre del alias es una API pública. Evita los nombres integrados como `auth` o `throttle` y los nombres genéricos que puedan chocar con otros paquetes, y añade un prefijo propio del paquete. Si vuelves a registrar la misma clave, `aliasMiddleware()` sobrescribe la correspondencia anterior.

## Publicar el alias desde el proveedor

En el siguiente ejemplo se crea un middleware que añade a la respuesta una cabecera de identificación fija. No es un ejemplo de autenticación, autorización ni control de acceso. Se asume que el PSR-4 de Composer asigna `Acme\Courier\` a `src/` y que el proveedor se registra mediante el [descubrimiento automático](/es/advanced/package-discovery) o manualmente.

```php src/Http/Middleware/AddCourierHeader.php theme={null}
<?php

namespace Acme\Courier\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class AddCourierHeader
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        $response->headers->set('X-Acme-Courier', 'enabled');

        return $response;
    }
}
```

El Router se usa en `boot()`. Los argumentos de `boot()` se inyectan desde el contenedor de servicios, así que no hace falta editar automáticamente el `bootstrap/app.php` del usuario para registrar el middleware.

```php src/CourierServiceProvider.php theme={null}
<?php

namespace Acme\Courier;

use Acme\Courier\Http\Middleware\AddCourierHeader;
use Illuminate\Routing\Router;
use Illuminate\Support\ServiceProvider;

class CourierServiceProvider extends ServiceProvider
{
    public function boot(Router $router): void
    {
        $router->aliasMiddleware('acme-courier.header', AddCourierHeader::class);
    }
}
```

Este proveedor debe arrancar como un proveedor normal. Si trasladas el registro del alias a un proveedor diferido que solo se ejecuta cuando se resuelve otro servicio, deja de estar garantizado que el alias esté registrado en el momento en que la ruta lo necesita.

### El usuario lo aplica ruta por ruta

En el `routes/web.php` de la aplicación que usa el paquete, se asigna solo a las rutas que lo necesitan.

```php routes/web.php theme={null}
<?php

use Illuminate\Support\Facades\Route;

Route::get('/courier-status', function () {
    return response()->json(['available' => true]);
})->middleware('acme-courier.header');
```

También puedes no ofrecer alias e indicar directamente el nombre de la clase, como en `->middleware(AddCourierHeader::class)`. Elige según si necesitas ofrecer al usuario un nombre corto.

Si el propio paquete proporciona rutas, indica también de forma explícita en el archivo de rutas el middleware necesario. `loadRoutesFrom()` no añade `web` ni `api` automáticamente. Para el método de registro y el tratamiento de la caché de rutas, consulta [Registro de rutas y caché en paquetes](/es/advanced/package-routes).

## La aplicación a toda la aplicación la elige el usuario

Si quiere aplicarlo a todas las rutas `web` de su aplicación, el usuario añade la siguiente configuración a su callback `withMiddleware()` existente. No es un ejemplo que sustituya la configuración existente.

```php theme={null}
use Acme\Courier\Http\Middleware\AddCourierHeader;
use Illuminate\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->web(append: [
        AddCourierHeader::class,
    ]);
})
```

En esta configuración se usa directamente el nombre de la clase, por lo que no depende del orden de registro del alias. El alcance es el grupo `web`, no la pila global. No se aplica automáticamente a `api` ni a las rutas que no tengan ninguno de los dos grupos.

<Warning>
  Diseñar el paquete para que se aplique a todo `web` al instalarlo no es compatible con un diseño en el que el usuario lo aplica de forma explícita. No extiendas a todas las rutas, mediante una actualización automática, procesos que afecten a la autenticación, las sesiones, las cabeceras de respuesta o las comunicaciones externas.
</Warning>

## Las operaciones de grupo del Router no son equivalentes

Si el paquete ofrece su propio grupo, usa un nombre propio. El siguiente ejemplo se coloca dentro del `boot(Router $router)` del proveedor.

```php theme={null}
$router->middlewareGroup('acme-courier', [
    AddCourierHeader::class,
]);
```

El usuario puede aplicarlo con `->middleware('acme-courier')`. Sin embargo, este grupo solo contiene las clases indicadas y no hereda la sesión ni la protección CSRF de `web`.

También existen APIs para añadir elementos a grupos existentes, pero en la implementación del Router de `v13.36.0` presentan las siguientes diferencias.

| Método del Router | Si el grupo existe | Si el grupo no existe |
| - | - | - |
| `middlewareGroup($name, $items)` | Sustituye todo el array | Lo crea con el array indicado |
| `pushMiddlewareToGroup($name, $item)` | Lo añade al final si no existe el mismo elemento | Crea un array vacío y luego lo añade |
| `prependMiddlewareToGroup($name, $item)` | Lo añade al principio si no existe el mismo elemento | No hace nada |

Si con `middlewareGroup('web', [...])` defines solo las clases del paquete, sustituyes el contenido existente de `web`. No lo confundas con los métodos para añadir. Además, hacer `pushMiddlewareToGroup()` sobre un `web` inexistente no restaura el grupo `web` estándar.

La detección de duplicados de los métodos para añadir se basa en el valor registrado. Un alias y un nombre de clase que apuntan a la misma clase son cadenas distintas, así que en la tabla de registro se consideran elementos diferentes. Unifica la notación y no des por hecho que, al registrar, se eliminarán los duplicados de una misma clase escrita de formas distintas.

### El orden de registro por sí solo no garantiza el orden de ejecución

El Router expande los alias y grupos del middleware asignado a la ruta, procesa las exclusiones y luego los ordena según la prioridad. Añadir al principio o al final no garantiza por sí solo una relación de orden estricta con la autenticación o el route model binding.

Además, `syncMiddlewareToRouter()` del HTTP Kernel sincroniza con el Router los grupos que tiene el Kernel mediante `middlewareGroup()`. Si la configuración del Kernel se vuelve a sincronizar más tarde, el contenido de los grupos añadido directamente al Router puede quedar sustituido. En lugar de competir con el orden de arranque entre paquetes para modificar grupos existentes, la norma básica es concentrar la configuración en el `withMiddleware()` de la aplicación que usa el paquete.

En las funcionalidades que requieran un orden concreto, como después de iniciar la sesión o después de la autenticación, indica ese requisito en las instrucciones de instalación y verifícalo junto con la configuración de prioridad de la aplicación que lo usa. Evita que el paquete sustituya por completo la lista de prioridades de toda la aplicación.

## Límites entre la caché y la verificación

No coloques el registro del alias dentro de una condición de `routesAreCached()` ni en un archivo de rutas. `loadRoutesFrom()` no carga el archivo de rutas si existe caché, pero sigue siendo necesario registrar el alias para resolver en tiempo de ejecución los alias que permanecen en las rutas cacheadas. Regístralo siempre en el `boot()` del proveedor.

Si cambias la asignación a las rutas, vuelve a generar la caché de rutas en la aplicación que usa el paquete.

```bash theme={null}
php artisan route:cache
php artisan route:list --path=courier-status -vv
```

`-vv` se usa para expandir y revisar el contenido de los grupos. Sin embargo, que el listado se muestre correctamente no garantiza el procesamiento dentro del middleware ni el uso de la sesión. También necesitas pruebas de peticiones HTTP.

El siguiente es un método que se añade a una prueba Feature de una aplicación Laravel que define la ruta `/courier-status` anterior.

```php theme={null}
public function test_courier_header_is_applied(): void
{
    $this->get('/courier-status')
        ->assertOk()
        ->assertHeader('X-Acme-Courier', 'enabled');
}
```

| Caso de verificación | Resultado esperado |
| - | - |
| Ruta en la que solo se ha registrado el alias | No se añade la cabecera |
| Ruta a la que se asigna el alias | Se añade la cabecera |
| Ruta a la que se asigna directamente el nombre de la clase | Mismo comportamiento |
| Arrancar una aplicación nueva después de generar la caché | Mismo comportamiento en la misma ruta |
| Elegir la aplicación a todo `web` | Se aplica a las rutas `web` de destino y no se extiende a las demás |
| Configurar grupos y prioridades propios de la aplicación que lo usa | El orden respecto a la sesión, la autenticación y el binding cumple los requisitos |

Las pruebas unitarias que comprueban si existe un grupo o revisan el array de alias son una verificación distinta de la ejecución HTTP real. En particular, la verificación de la caché no debe limitarse a inspeccionar el Router del mismo proceso, sino hacerse en un arranque nuevo después de generar la caché. Si usas workers de larga duración, recárgalos siguiendo el procedimiento de despliegue habitual.

## Páginas relacionadas

<Columns cols={2}>
  <Card title="Middleware" icon="layer-group" href="/es/middleware">
    Revisa los fundamentos de la creación, la aplicación a rutas, los parámetros y la prioridad.
  </Card>

  <Card title="Registro de rutas y caché en paquetes" icon="route" href="/es/advanced/package-routes">
    Revisa la relación entre la carga de rutas y la configuración al generar la caché.
  </Card>
</Columns>

## Fuentes primarias consultadas

* [Documentación oficial de Laravel: Middleware](https://github.com/laravel/docs/blob/6bb0a3be3c623f7964c8277625a07b6df7f1de2e/middleware.md)
* [Documentación oficial de Laravel: boot de los proveedores de servicios e inyección de dependencias](https://github.com/laravel/docs/blob/6bb0a3be3c623f7964c8277625a07b6df7f1de2e/providers.md#the-boot-method)
* [Router: registro de alias, operaciones de grupo, expansión y ordenación del middleware](https://github.com/laravel/framework/blob/v13.36.0/src/Illuminate/Routing/Router.php)
* [HTTP Kernel: syncMiddlewareToRouter](https://github.com/laravel/framework/blob/v13.36.0/src/Illuminate/Foundation/Http/Kernel.php)


## Related topics

- [Laravel Fetch Metadata](/es/packages/laravel-fetch-metadata.md)
- [Registro de rutas y caché en paquetes](/es/advanced/package-routes.md)
- [Desarrollo de paquetes para Laravel](/es/advanced/package-development.md)
- [Temas avanzados](/es/advanced/index.md)
- [Registro y caché de listeners de eventos en paquetes](/es/advanced/package-events.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.