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/customersfonctionnel,- endpoint
/api/logs/errorsprêt (ou à créer – cf. doc logging). - Un projet Angular (SeckShop Front) créé avec Angular CLI.
Étape 1 – Configuration environnement
- Dans
environment.tsetenvironment.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'
};
- Vérifier que le backend répond bien sur
http://localhost:8080/api.
Étape 2 – Créer un LoggerService Angular
- 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
LoggingInterceptorHTTP 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.