13.x y la implementación de Framework v13.36.0. Para saber cómo escribir un middleware normal, consulta 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.
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 asignaAcme\Courier\ a src/ y que el proveedor se registra mediante el descubrimiento automático o manualmente.
src/Http/Middleware/AddCourierHeader.php
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.
src/CourierServiceProvider.php
El usuario lo aplica ruta por ruta
En elroutes/web.php de la aplicación que usa el paquete, se asigna solo a las rutas que lo necesitan.
routes/web.php
->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.
La aplicación a toda la aplicación la elige el usuario
Si quiere aplicarlo a todas las rutasweb 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.
web, no la pila global. No se aplica automáticamente a api ni a las rutas que no tengan ninguno de los dos grupos.
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 delboot(Router $router) del proveedor.
->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.
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 deroutesAreCached() 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.
-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.
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
Middleware
Revisa los fundamentos de la creación, la aplicación a rutas, los parámetros y la prioridad.
Registro de rutas y caché en paquetes
Revisa la relación entre la carga de rutas y la configuración al generar la caché.