Skip to main content

Overview

Biblioteca Virtual Frontend is built with Angular 19 using modern standalone components architecture. The application follows a feature-based folder structure with clear separation of concerns between authentication, core services, and feature modules.

Technology Stack

Angular 19

Standalone components with functional guards and interceptors

TypeScript

Strongly-typed application logic and interfaces

JWT Authentication

Token-based authentication with HTTP interceptors

Role-Based Access

Admin and User role management with route guards

Folder Structure

The application follows a clear, feature-based architecture that promotes maintainability and scalability:
src/app/
├── auth/                          # Authentication feature module
│   ├── login/                     # Login component
│   ├── registro/                  # Registration component
│   └── auth.service.ts            # Authentication service

├── core/                          # Core application services
│   ├── guards/                    # Route protection guards
│   │   ├── auth-guard.ts         # Authentication guard
│   │   ├── admin-guard.ts        # Admin authorization guard
│   │   └── public-guard.ts       # Public routes guard
│   │
│   ├── interceptors/             # HTTP interceptors
│   │   └── auth-interceptor.ts   # JWT token interceptor
│   │
│   ├── models/                   # TypeScript interfaces
│   │   ├── auth.interface.ts     # Auth request/response types
│   │   ├── libro.ts              # Book model
│   │   ├── autor.ts              # Author model
│   │   ├── genero.ts             # Genre model
│   │   └── prestamo.ts           # Loan model
│   │
│   └── services/                 # Core services
│       └── token-storage.service.ts  # Token management

├── features/                     # Feature modules
│   ├── catalogo/                # Book catalog (user view)
│   ├── libros/                  # Book management (admin)
│   │   ├── libro-list/
│   │   └── libro-form/
│   ├── autores/                 # Author management (admin)
│   │   ├── autor-list/
│   │   └── autor-form/
│   ├── generos/                 # Genre management (admin)
│   │   ├── genero-list/
│   │   └── genero-form/
│   └── prestamos/               # Loan management (admin)
│       └── prestamo-list/

├── shared/                      # Shared components
│   └── components/
│       └── navbar/              # Navigation bar

├── app.ts                       # Root component
├── app.config.ts                # Application configuration
└── app.routes.ts                # Routing configuration

Standalone Components Architecture

The application leverages Angular’s modern standalone components pattern, eliminating the need for NgModules:
src/app/app.ts
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { NavbarComponent } from './shared/components/navbar/navbar';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet, NavbarComponent],
  templateUrl: './app.html',
  styleUrl: './app.css',
})
export class App {
  protected title = 'biblioteca-front';
}
All components in this application are standalone, directly importing their dependencies without NgModules. This simplifies the architecture and improves tree-shaking.

Application Configuration

The application is bootstrapped using functional configuration providers:
src/app/app.config.ts
import {
  ApplicationConfig,
  provideBrowserGlobalErrorListeners,
  provideZoneChangeDetection,
} from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import {
  provideHttpClient,
  withFetch,
  withInterceptors,
} from '@angular/common/http';
import { authInterceptor } from './core/interceptors/auth-interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideBrowserGlobalErrorListeners(),
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    
    // HTTP Client with JWT interceptor
    provideHttpClient(withFetch(), withInterceptors([authInterceptor])),
  ],
};

Key Configuration Features

1

Router Configuration

Routes are provided using provideRouter(routes) with all route definitions from app.routes.ts
2

HTTP Client Setup

provideHttpClient is configured with:
  • withFetch() - Uses the modern Fetch API
  • withInterceptors([authInterceptor]) - Automatically adds JWT tokens to requests
3

Zone Change Detection

Optimized with event coalescing for better performance
4

Global Error Listeners

Centralized error handling across the application

Design Patterns

1. Service-Based Architecture

All business logic is encapsulated in injectable services:
  • AuthService - Handles login, registration, and session management
  • TokenStorageService - Manages JWT token storage in localStorage
  • Domain services for Books, Authors, Genres, and Loans

2. Functional Guards

Modern functional route guards replace class-based guards:
export const authGuard: CanActivateFn = (route, state) => {
  const tokenStorage = inject(TokenStorageService);
  const router = inject(Router);
  
  const token = tokenStorage.getToken();
  
  if (token) {
    return true;
  } else {
    router.navigate(['/auth/login']);
    return false;
  }
};

3. HTTP Interceptors

Functional interceptors automatically attach JWT tokens to outgoing requests:
src/app/core/interceptors/auth-interceptor.ts
export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const tokenStorage = inject(TokenStorageService);
  const token = tokenStorage.getToken();

  if (!token) {
    return next(req);
  }

  const clonedRequest = req.clone({
    setHeaders: {
      Authorization: `Bearer ${token}`,
    },
  });

  return next(clonedRequest);
};

4. TypeScript Interfaces

Strong typing ensures type safety across the application:
src/app/core/models/auth.interface.ts
export interface AuthRequest {
  username: string;
  password: string;
}

export interface AuthResponse {
  token: string;
  tipoToken: string;
  username: string;
  role: string;
}

Feature Modules Organization

Each feature follows a consistent structure:
Display data in tables with CRUD operations
  • libro-list
  • autor-list
  • genero-list
  • prestamo-list

Core Principles

Separation of Concerns

Authentication, core services, and features are clearly separated

Single Responsibility

Each service, guard, and component has a focused purpose

Dependency Injection

All services use Angular’s DI system for loose coupling

Type Safety

TypeScript interfaces ensure compile-time type checking

Next Steps

Routing

Learn about route configuration and navigation

Authentication

Understand the JWT authentication flow

Authorization

Explore role-based access control with guards

Services

See how to integrate with backend services

Build docs developers (and LLMs) love