Ir al contenido

Release 8: Navegación y asociaciones en el front

Objetivo: que el front alcance al back. Al terminar, la aplicación navega entre los módulos del grupo con el Router de Angular, tiene un menú de navegación, muestra el detalle de un recurso a partir de su id en la URL, y permite crear asociaciones entre entidades llamando a los endpoints que el back expuso en el Release 7. Las pruebas del front corren en el pipeline.


En la clase 1 el equipo hace el taller de layout y look and feel: revisa los prototipos de la semana 1, construye un prototipo nuevo en HTML y registra en la wiki, antes de tocar el código:

  1. Las rutas de la aplicación: mínimo una ruta raíz por módulo (/artistas, /disqueras, …) y la ruta del detalle de cada recurso (/artistas/:id).
  2. La organización del menú: un menú global en AppComponent o uno por módulo.
  3. Las vistas de asociación: una vista separada o un botón dentro del detalle.

IA permitida aquí: se puede pedir a Gemini una lista de ventajas y desventajas de un menú global frente a uno por módulo. La decisión es del equipo.


Hasta ahora la aplicación mostraba sus componentes uno debajo de otro en app.html. Con el Router, cada vista tiene su propia URL.

  • provideRouter(routes) en app.config.ts.
  • Las rutas en app.routes.ts: una por vista, una redirección desde la raíz y una ruta que atrapa las URL que no existen.
  • <router-outlet /> en el template de AppComponent: es el lugar donde Angular pinta el componente de la ruta activa.

El tutorial de rutas y menú construye esto paso a paso, y la teoría está en Enrutamiento y Angular Router.

IA permitida aquí: el archivo app.routes.ts y los componentes análogos se pueden pedir a Gemini. El estudiante verifica que cada ruta apunta a un componente que existe y que las URL que no existen llevan a la ruta de respaldo.


El menú sigue el acuerdo de la wiki. Cada enlace usa routerLink, y todos llevan routerLinkActive para marcar el enlace de la ruta en la que está el usuario. El menú se construye con los componentes de Bootstrap que ya conoces, y el tutorial de rutas y menú lo hace paso a paso.


En el Release 4 el detalle recibía el dato ya cargado: la lista traía el objeto y el detalle solo lo mostraba, sin pedir nada al back. Ese diseño sigue siendo válido cuando la lista ya trae todo lo que el detalle necesita.

Hay un segundo tipo de detalle, que va al back por el id: el que necesita información que la lista no trajo. Por eso:

  • El detalle recibe el id por la ruta (/artistas/:id) y pide el recurso a GET /<entidades>/{id}.
  • Maneja el caso en que el back responde 404.
  • La lista navega al detalle con [routerLink].

El detalle del álbum es el caso que lo hace necesario: el ArtistaDTOCompleto trae los álbumes sin sus canciones, así que el detalle del álbum pide GET /albumes/{id}, que responde un AlbumDTOCompleto con ellas. Las canciones, que quedaron fuera del front en el Release 7, vuelven aquí. El tutorial del detalle por ruta lo construye paso a paso, con el detalle del artista y el del álbum.


Por cada asociación inter-módulo acordada en el Release 7, el integrante cuyo módulo contiene el recurso dueño escribe un componente que:

  • Carga las opciones del otro módulo (la lista del recurso asociado) y las muestra en un selector.
  • Llama al endpoint de asociación (POST /<entidades>/{id}/<asociados>/{asociadoId}) con la opción elegida.
  • Si el back responde un error (400 si la asociación ya existe, 404 si alguno de los recursos no existe), muestra el mensaje que el back envía en el cuerpo.
  • Si la asociación se crea, navega de vuelta al detalle, donde se ve el resultado.
  • Maneja el caso en que no hay opciones para elegir.

El integrante del módulo asociado expone su servicio para que el componente lo use. El tutorial de asociación construye este componente para artistas y álbumes.


Cada componente de asociación se registra en app.routes.ts (por ejemplo, artistas/:id/add-album) y se enlaza desde el detalle del recurso dueño, según lo decidido en el acuerdo de navegación. El tutorial de asociación lo muestra.

IA permitida aquí: el menú, las rutas y los componentes análogos al primer componente de asociación se pueden pedir a Gemini. El estudiante verifica que el selector maneja el caso sin opciones y que la navegación después de asociar lleva al lugar correcto.


El pipeline ya ejecuta las pruebas del front (pnpm test, que usa Vitest) y las publica en SonarQube, igual que las del back. Por cada módulo se escriben, como mínimo:

Prueba Qué comprueba Mínimo
Servicio La URL, el verbo y el cuerpo de las llamadas al back 1
Ruta Que la URL del detalle muestra el componente correcto con el recurso que responde el back, y que un 404 se maneja 1
Componente de asociación Que llama al endpoint correcto y que muestra el mensaje del back cuando la asociación falla 2 (éxito y error)
Contrato Que una respuesta real del back, guardada como ejemplo, cabe en el modelo TypeScript del front 1

Cada prueba se simula con respuestas HTTP controladas, sin levantar el back. El tutorial de pruebas del front con Vitest las escribe paso a paso para un módulo, y la teoría está en Pruebas del front con Vitest. Como en las pruebas del Service, una prueba que nunca falla no protege nada: después de escribirla, rómpela a propósito (cambia la URL, quita el manejo del error) y comprueba que falla.

IA permitida aquí: las pruebas análogas a la primera se pueden pedir a Gemini. El estudiante verifica que cada prueba realmente falla cuando se rompe el código que protege.


Con el back del grupo corriendo, el equipo recorre la aplicación completa: navegar entre los módulos con el menú, crear un recurso, abrir su detalle por ruta, asociarlo desde el componente de asociación y ver la relación en el detalle.

Extra para quien quiera: automatizar ese recorrido con una prueba de punta a punta en Playwright. Es la única forma de detectar un error de CORS antes de que lo encuentre un usuario. No se entrega ni corre en el pipeline. La teoría explica qué prueba y en qué se diferencia de Vitest, y el tutorial construye el recorrido.


  • app.routes.ts es compartido: lo actualiza solo quien tiene el PR activo.
  • El componente de asociación lo escribe el integrante del módulo dueño; el del módulo asociado expone su servicio.
  • Si un componente depende de un servicio que todavía no está en main, el PR espera. No se simula el servicio de otro módulo en el código entregado.
  • Los PRs se mergean uno a la vez, y un PR con pruebas del front en rojo no se aprueba.
  • Si el pipeline falla después de un merge, máxima prioridad del equipo: se revierte y se investiga en rama aparte.

  • Página “Diseño de la interfaz” en la wiki, con el prototipo en HTML (carpeta docs/), el layout, la tabla de rutas, el menú y la guía de estilo, y una aplicación que la sigue.
  • Router configurado, con rutas para todos los módulos del grupo y una ruta de respaldo.
  • Menú de navegación según el acuerdo de la wiki, con routerLinkActive en todos los enlaces.
  • Componentes de detalle que reciben el id por la ruta, con el caso 404 manejado.
  • El detalle del álbum muestra sus canciones, pedidas a GET /albumes/{id}.
  • Un componente de asociación por cada asociación inter-módulo acordada en el Release 7, con su ruta registrada en app.routes.ts y el mensaje del back cuando falla.
  • Pruebas del front en Vitest por módulo (servicio, ruta, componente de asociación y contrato), en verde en el pipeline.
  • La aplicación navega entre módulos, crea recursos, los asocia y muestra el resultado en el detalle.