Aller au contenu

TP SeckShop – Frontend (Angular + Logging)

Objectif : montrer à un développeur front comment brancher un frontend Angular sur un backend SeckShop et remonter les erreurs front dans le logging centralisé (via un endpoint /api/logs/errors).

Durée cible : 1/2 journée.


Étape 0 – Pré‑requis

  • Backend SeckShop du TP précédent en place, avec :
  • /api/customers fonctionnel,
  • endpoint /api/logs/errors prêt (ou à créer – cf. doc logging).
  • Un projet Angular (SeckShop Front) créé avec Angular CLI.

Étape 1 – Configuration environnement

  1. Dans environment.ts et environment.prod.ts, ajouter :
export const environment = {
  production: false, // ou true en prod
  apiBaseUrl: 'http://localhost:8080/api',
  logging: {
    provider: 'http',
    endpoint: 'http://localhost:8080/api/logs/errors'
  },
  tenantCode: 'seckshop'
};
  1. Vérifier que le backend répond bien sur http://localhost:8080/api.

Étape 2 – Créer un LoggerService Angular

  1. Créer src/app/services/logger.service.ts :
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';

interface FrontLogPayload {
  message: string;
  component?: string;
  action?: string;
  tenant?: string;
  url?: string;
  userAgent?: string;
}

@Injectable({ providedIn: 'root' })
export class LoggerService {
  private endpoint = environment.logging.endpoint;

  constructor(private http: HttpClient) {}

  logError(message: string, error?: unknown, context: Partial<FrontLogPayload> = {}): void {
    const payload: FrontLogPayload = {
      message,
      component: context.component,
      action: context.action,
      tenant: environment.tenantCode,
      url: window.location.href,
      userAgent: navigator.userAgent
    };

    // Fire‑and‑forget : on ne bloque jamais l’UX sur le logging
    this.http.post(this.endpoint, payload).subscribe({
      next: () => {},
      error: () => {}
    });
  }
}

Objectif : avoir un point d’entrée unique pour les logs front.


Étape 3 – Utiliser le logger dans un composant

Exemple avec un composant CustomersComponent qui appelle /api/customers :

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
import { LoggerService } from '../services/logger.service';

interface Customer {
  id: string;
  firstName: string;
  lastName: string;
  email: string;
}

@Component({
  selector: 'app-customers',
  templateUrl: './customers.component.html'
})
export class CustomersComponent implements OnInit {
  customers: Customer[] = [];
  loading = false;

  constructor(private http: HttpClient, private logger: LoggerService) {}

  ngOnInit(): void {
    this.loadCustomers();
  }

  loadCustomers(): void {
    this.loading = true;
    this.http.get<Customer[]>(`${environment.apiBaseUrl}/customers`).subscribe({
      next: (data) => {
        this.customers = data;
        this.loading = false;
      },
      error: (err) => {
        this.loading = false;
        this.logger.logError('Erreur lors du chargement des customers', err, {
          component: 'CustomersComponent',
          action: 'loadCustomers'
        });
      }
    });
  }
}

Objectif : toute erreur front critique remonte dans le backend via /api/logs/errors.


Étape 4 – Côté backend : endpoint /api/logs/errors

Rappel côté backend (SeckShop) :

@RestController
@RequestMapping("/api/logs")
public class LoggingController {

    @Autowired
    private DynorsLogger logger;

    @PostMapping("/errors")
    public ResponseEntity<Void> logError(@RequestBody FrontErrorLogDto dto) {
        logger.error(dto.getMessage(), null, Map.of(
            "service", "Frontend",
            "component", dto.getComponent(),
            "action", dto.getAction(),
            "tenant", dto.getTenant(),
            "url", dto.getUrl(),
            "userAgent", dto.getUserAgent()
        ));
        return ResponseEntity.ok().build();
    }
}

L’idée : centraliser tous les logs back + front via DynorsLogger et le provider choisi (console / sentry / autre).


Étape 5 – Tests & vérifications

  • Forcer une erreur front (ex : couper le backend, déclencher un 0/0, etc.).
  • Vérifier :
  • que le frontend n’explose pas (UX gérée),
  • que l’erreur est bien envoyée sur /api/logs/errors,
  • qu’elle apparaît dans les logs backend (console ou Sentry).

Étape 6 – Aller plus loin (optionnel)

  • Ajouter un LoggingInterceptor HTTP côté Angular pour logger :
  • les erreurs 4xx/5xx globales,
  • éventuellement des métriques (latence, URLs les plus appelées).
  • Ajouter un provider: 'sentry' côté front pour les cas où tu veux aussi un canal direct Sentry.