Skip to main content

Overview

Biblioteca Virtual uses Angular’s standalone routing system with functional route guards. The routing configuration defines access control for public routes (login/register), authenticated user routes (catalog), and admin-only routes (management pages).

Route Configuration

All routes are defined in app.routes.ts with appropriate guards for access control:
src/app/app.routes.ts
import { Routes } from '@angular/router';
import { authGuard } from './core/guards/auth-guard';
import { publicGuard } from './core/guards/public-guard';
import { adminGuard } from './core/guards/admin-guard';

export const routes: Routes = [
  // Default redirect to login
  { path: '', redirectTo: 'auth/login', pathMatch: 'full' },

  // Public routes (unauthenticated users only)
  { path: 'auth/login', component: LoginComponent, canActivate: [publicGuard] },
  { path: 'auth/registro', component: RegistroComponent, canActivate: [publicGuard] },

  // User routes (authenticated users)
  { path: 'catalogo', component: CatalogoComponent, canActivate: [authGuard] },

  // Admin routes (authenticated admins only)
  { path: 'libros', component: LibroListComponent, canActivate: [authGuard, adminGuard] },
  { path: 'libros/nuevo', component: LibroFormComponent, canActivate: [authGuard, adminGuard] },
  { path: 'libros/editar/:id', component: LibroFormComponent, canActivate: [authGuard, adminGuard] },
  
  { path: 'autores', component: AutorListComponent, canActivate: [authGuard, adminGuard] },
  { path: 'autores/nuevo', component: AutorFormComponent, canActivate: [authGuard, adminGuard] },
  { path: 'autores/editar/:id', component: AutorFormComponent, canActivate: [authGuard, adminGuard] },
  
  { path: 'generos', component: GeneroListComponent, canActivate: [authGuard, adminGuard] },
  { path: 'generos/nuevo', component: GeneroFormComponent, canActivate: [authGuard, adminGuard] },
  { path: 'generos/editar/:id', component: GeneroFormComponent, canActivate: [authGuard, adminGuard] },
  
  { path: 'prestamos', component: PrestamoListComponent, canActivate: [authGuard, adminGuard] },

  // Wildcard - redirect to login
  { path: '**', redirectTo: 'auth/login' },
];

Route Categories

Public Routes

Public routes are accessible only to unauthenticated users. The publicGuard redirects logged-in users to their appropriate dashboard.
{
  path: 'auth/login',
  component: LoginComponent,
  canActivate: [publicGuard]
}
When a logged-in user tries to access /auth/login, they are automatically redirected to:
  • /libros (admins)
  • /catalogo (regular users)

Authenticated User Routes

Routes that require authentication but are available to both users and admins:
User Catalog Route
{
  path: 'catalogo',
  component: CatalogoComponent,
  canActivate: [authGuard]  // Any authenticated user
}

Admin-Only Routes

Admin routes use both authGuard and adminGuard to ensure the user is authenticated AND has admin privileges:
// List all books
{ path: 'libros', component: LibroListComponent, canActivate: [authGuard, adminGuard] }

// Create new book
{ path: 'libros/nuevo', component: LibroFormComponent, canActivate: [authGuard, adminGuard] }

// Edit existing book
{ path: 'libros/editar/:id', component: LibroFormComponent, canActivate: [authGuard, adminGuard] }

Guard Execution Order

When multiple guards are specified, they execute in order from left to right:
canActivate: [authGuard, adminGuard]
1

authGuard executes first

Checks if the user has a valid JWT token
  • Pass: Continue to next guard
  • Fail: Redirect to /auth/login
2

adminGuard executes second

Checks if the user’s role is ROLE_ADMIN
  • Pass: Allow access to route
  • Fail: Redirect to /catalogo
Guards must be in the correct order. Placing adminGuard before authGuard could cause errors if the user is not authenticated.

Route Parameters

Edit routes use dynamic route parameters to identify which resource to edit:
{ path: 'libros/editar/:id', component: LibroFormComponent }

Accessing Route Parameters

In the component, access the id parameter using Angular’s ActivatedRoute:
import { ActivatedRoute } from '@angular/router';

export class LibroFormComponent {
  private route = inject(ActivatedRoute);
  
  ngOnInit() {
    const id = this.route.snapshot.params['id'];
    // Load book with this ID
  }
}

Programmatic Navigation

Navigate using Angular’s Router service:
import { Router } from '@angular/router';

export class SomeComponent {
  private router = inject(Router);
  
  goToBookList() {
    this.router.navigate(['/libros']);
  }
  
  editBook(id: number) {
    this.router.navigate(['/libros/editar', id]);
  }
  
  createNewBook() {
    this.router.navigate(['/libros/nuevo']);
  }
}

Template Navigation

Use routerLink directive in templates:
<!-- Navigate to list -->
<a routerLink="/libros">Ver Libros</a>

<!-- Navigate to create -->
<button (click)="router.navigate(['/libros/nuevo'])">Nuevo Libro</button>

<!-- Navigate to edit with ID -->
<a [routerLink]="['/libros/editar', libro.id]">Editar</a>

Redirect Behavior

Default Redirect

When users access the root path /, they are redirected to login:
{ path: '', redirectTo: 'auth/login', pathMatch: 'full' }

404 Handling

Unknown routes redirect to login:
{ path: '**', redirectTo: 'auth/login' }

Role-Based Redirects

The publicGuard implements intelligent redirects based on user role:
src/app/core/guards/public-guard.ts
if (token) {
  const role = localStorage.getItem('role');
  
  if (role === 'ROLE_ADMIN') {
    router.navigate(['/libros']);      // Admins → Book management
  } else {
    router.navigate(['/catalogo']);    // Users → Catalog
  }
  
  return false;
}

Route Protection Summary

Route PatternGuardsAccess
/auth/loginpublicGuardUnauthenticated users only
/auth/registropublicGuardUnauthenticated users only
/catalogoauthGuardAny authenticated user
/libros/*authGuard, adminGuardAdmins only
/autores/*authGuard, adminGuardAdmins only
/generos/*authGuard, adminGuardAdmins only
/prestamosauthGuard, adminGuardAdmins only

Common CRUD Patterns

Most admin features follow this routing pattern:
{ path: 'resource', component: ResourceListComponent, canActivate: [authGuard, adminGuard] }
The same form component (ResourceFormComponent) is used for both create and edit operations. The presence of an id parameter determines which mode to use.

Best Practices

Always Use Guards

Every route should have appropriate guards to prevent unauthorized access

Guard Order Matters

Place authGuard before adminGuard to ensure proper authentication checks

Reuse Form Components

Use the same component for create and edit by checking route parameters

Fallback Routes

Always define a wildcard route to handle 404 scenarios

Next Steps

Authentication

Learn how JWT authentication works

Authorization Guards

Deep dive into guard implementation

Navigation Component

Explore the navbar component

Form Components

Build CRUD forms with routing

Build docs developers (and LLMs) love