Migrar AngularJS que vive dentro de ASP.NET MVC
Muchas apps AngularJS nunca fueron independientes. Crecieron dentro de proyectos ASP.NET MVC, con Razor renderizando parte de la página. Antes de mover el frontend hay que desatar cuatro nudos entre cliente y servidor.
Cómo es este tipo de app
Un proyecto típico tiene un controlador MVC que devuelve una vista Razor. El archivo de layout renderiza la navegación y los bundles de scripts. La vista contiene un atributo ng-app, y desde ahí AngularJS toma el control. Muchas veces cada vista MVC aloja su propio módulo AngularJS pequeño, y el producto es un conjunto de mini aplicaciones conectadas por cargas completas de página.
Para una migración esto significa que el frontend no se puede mover solo. Hay cuatro cosas que lo atan al servidor.
Nudo 1: Razor dentro de los templates
Los templates de AngularJS se sirven muchas veces como vistas parciales Razor. Eso le permite al servidor decidir qué entra en el template:
- Validaciones de rol que incluyen o quitan un botón.
- Etiquetas localizadas desde archivos de recursos.
- Datos del modelo serializados en la página o en
ng-init.
Un build moderno de Angular compila sus templates de antemano. No puede consumir un template que el servidor cambia en cada solicitud.
Cómo desatarlo
- Lista cada template que contenga expresiones Razor.
- Lleva los permisos a un endpoint que devuelva lo que el usuario actual puede hacer. El cliente muestra u oculta elementos según esos datos. El servidor sigue aplicando las reglas en cada llamada al API.
- Lleva los textos localizados a archivos JSON o a un endpoint que el cliente cargue.
- Reemplaza los datos inyectados del modelo por llamadas al API.
- Convierte las vistas parciales en templates HTML estáticos.
Después de este paso el frontend antiguo sigue siendo AngularJS, y ahora habla con el servidor solo por HTTP. Esa es la condición previa para todo lo demás.
Nudo 2: Bundling
Los proyectos MVC clásicos empaquetan los scripts en el servidor, con la configuración de bundles en C# y helpers de renderizado en el layout. Angular necesita un build basado en Node, que genera sus propios archivos con hash.
Cómo desatarlo
- Agrega el workspace de Angular al repositorio y constrúyelo en CI antes del build de .NET.
- Publica el resultado como archivos estáticos en el mismo sitio.
- Haz que el layout referencie los archivos generados. Como los nombres llevan hash, léelos desde el resultado del build, o sirve directamente el
index.htmlgenerado para las rutas de la SPA.
Nudo 3: Cookies de autenticación
Las aplicaciones MVC normalmente autentican a los usuarios con una cookie. Es una buena noticia: una SPA servida desde el mismo sitio envía esa cookie de forma automática, y los usuarios conservan un solo inicio de sesión. Hay dos detalles que atender.
- Sesiones expiradas. Por defecto, la autenticación por cookies responde a una solicitud no autenticada con una redirección a la página de login. Una llamada al API desde la SPA recibe entonces el HTML del login en lugar de un error. Configura las rutas del API para que devuelvan un estado 401 y manéjalo en un único interceptor HTTP.
- Tokens anti-forgery. Los formularios Razor llevan un token oculto. Las llamadas al API necesitan la misma protección mediante un header. El cliente HTTP de Angular puede leer un token desde una cookie y enviarlo como header, y ASP.NET puede validar ese header. Configura ambos lados y prueba un POST temprano.
No reemplaces el mecanismo de autenticación en la misma fase que las primeras pantallas migradas. Pasar de cookies a tokens con un proveedor de identidad es un proyecto válido. Hazlo por separado, antes o después, para que cada cambio se pueda probar y revertir de forma independiente.
Nudo 4: Rutas repartidas entre servidor y cliente
En el modelo antiguo, las rutas MVC eligen la página y las rutas de AngularJS funcionan dentro de ella. En el modelo de destino, el router del cliente es dueño de las URLs de la aplicación y el servidor expone un API.
Cómo desatarlo
- Reserva un prefijo de ruta para el API, por ejemplo
/api. - Agrega una ruta de respaldo para que cualquier URL de la aplicación devuelva la página de entrada de la SPA. Así funcionan los enlaces profundos y el refresco.
- Mantén las páginas MVC restantes en sus rutas actuales hasta migrarlas. El proxy o la tabla de rutas de MVC decide qué URLs siguen siendo de Razor.
Un orden que funciona
- Diagnóstico: inventario de vistas, expresiones Razor en templates y endpoints.
- Desatar el nudo 1 dentro de la app AngularJS. Sin cambios visibles para el usuario.
- Montar el build de Angular y la aplicación híbrida (nudo 2).
- Corregir el comportamiento del 401 y del anti-forgery (nudo 3).
- Agregar la ruta de respaldo (nudo 4) y migrar la primera pantalla.
- Seguir pantalla por pantalla, como se describe en Cómo migrar de AngularJS a Angular sin downtime.
Mantén separada la actualización del backend
Si además está planificado el paso de .NET Framework al .NET actual, hazlo como un proyecto propio. Con un API entre ambos, cada lado se puede actualizar por separado.
Las páginas que mezclan Razor con jQuery siguen un camino parecido, descrito en la guía de migración de jQuery. El equivalente de esta guía para Java es AngularJS con Java y JSP.
Más en esta sección
- Migrar AngularJS que vive dentro de Java y JSP
- Cómo seguir entregando funcionalidades durante una migración
- Cómo medir el avance de una migración
- Después de la migración: mantener el frontend al día
¿Planeas una migración o una plataforma de microfrontends?
En una llamada de 20 minutos me cuentas tu situación y te digo cómo la abordaría. Si todavía no vale la pena, también te lo digo.
Escríbeme por LinkedIn