Files
SkydiveLogs/Back/analyse.md
T
2026-03-24 22:11:58 +01:00

19 KiB

Analyse de l'API C# SkydiveLogs - Architecture et Fonctionnement

Vue d'ensemble

L'API SkydiveLogs est une application ASP.NET Core MVC développée avec une architecture modulaire propre, divisée en six projets distincts qui reposent sur une architecture en couches (Layered Architecture) :

Structure du Projet

SkydiveLogs/Back/
├── skydiveLogs-api/              # Projet principal (Web API + Point d'entrée)
├── skydiveLogs-api.Domain/       # Modèles de domaine (Entités)
├── skydiveLogs-api.DomainBusiness/ # Couche business logique (Services)
├── skydiveLogs-api.DomainService/ # Couche d'accès aux données (Repositories)
├── skydiveLogs-api.Infrastructure/ # Implémentations des repositories
├── skydiveLogs-api.Ioc/          # Service d'injection de dépendances
└── skydiveLogs-api.sln           # Fichier de solution

1. Architecture des Couches

1.1 Architecture Clean/Modulaire

L'API suit le pattern Clean Architecture avec une séparation claire des responsabilités :

┌─────────────────────────────────────────────────────┐
│  skydiveLogs-api (Presentation Layer)                │
│  - Controllers                                       │
│  - Program.cs / Startup.cs                           │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.Ioc (Dependency Injection)          │
│  - Configuration IoC                                 │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.DomainBusiness (Business Layer)     │
│  - Services (Interfaces + Implémentations)           │
│  - Logique métier                                     │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.DomainService (Data Access Layer)   │
│  - Repositories (Interfaces)                         │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.Infrastructure (Implementation)     │
│  - Repositories implémentés                           │
│  - LiteDbProvider                                     │
└────────────────┬────────────────────────────────────┘
                 │
┌────────────────▼────────────────────────────────────┐
│  skydiveLogs-api.Domain (Domain Layer)               │
│  - Modèles de données (Entities)                     │
└─────────────────────────────────────────────────────┘

1.2 Injection de Dépendances (IocService)

Le projet skydiveLogs-api.Ioc gère toute l'injection de dépendances via la classe IocService :

Services Injectés

  • Aircraft, Gear, DropZone, Jump, JumpType, Tunnel, User et leurs services
  • Stats services (analytique)
  • CacheService (singleton pour le cache)
  • IdentityService (authentification)
  • Repositories pour chaque entité
  • LiteDbProvider (fournisseur de données LiteDB)
services.AddScoped<IAircraftService, AircraftService>();
services.AddScoped<IGearService, GearService>();
services.AddScoped<IDropZoneService, DropZoneService>();
services.AddScoped<IJumpService, JumpService>();
// ... et ainsi de suite pour tous les services

2. Configuration de l'Application (Startup.cs)

2.1 Configuration de l'Application

Le fichier Startup.cs configure :

  1. Authentication JWT

    • Validation du token JWT avec :
      • Vérification de l'émetteur (issuer)
      • Vérification de l'audience (audience)
      • Vérification de l'expiration (lifetime)
      • Validation de la clé de signature
  2. CORS

    • Configuration pour autoriser la communication avec l'application front-end
  3. Initialisation de la Base de Données

    • Vérification de l'existence du fichier LiteDB
    • Appel à InitDbService.GenerateDb() si le fichier n'existe pas
    • Appel à InitDbService.Update() si le fichier existe

2.2 Programme Principal (Program.cs)

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) 
    => WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();

3. Architecture des Contrôleurs

Tous les contrôleurs héritent de la classe de base Base :

3.1 Classe Base

[Route("api/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class Base : ControllerBase { }

Annotations importantes :

  • Route("api/[controller]") : Préfixe "api/" pour toutes les routes
  • ApiController : Optimisations pour les API
  • Authorize : Requêtes authentifiées via JWT

3.2 Structure Type des Contrôleurs

Chaque contrôleur suit le même pattern :

public class XxxController : Base
{
    public XxxController(IxxxService xxxService, IMapper mapper)
    {
        _xxxService = xxxService;
        _mapper = mapper;
    }
    
    [HttpGet]
    public IEnumerable<XxxResp> Get() { ... }
    
    [HttpGet("{id}")]
    public XxxResp Get(int id) { ... }
    
    [HttpPost]
    public void Post([FromBody] XxxReq value) { ... }
    
    [HttpPut("{id}")]
    public void Put(int id, [FromBody] XxxReq value) { ... }
    
    [HttpDelete("{id}")]
    public void Delete(int id) { ... }
}

4. Entités de Domaine (skydiveLogs-api.Domain)

4.1 Entités Principales

Jump (Saut de parachutisme)

public class Jump
{
    public Aircraft Aircraft { get; set; }
    public int DeployAltitude { get; set; }
    public DropZone DropZone { get; set; }
    public int ExitAltitude { get; set; }
    public Gear Gear { get; set; }
    public int Id { get; set; }
    public bool IsSpecial { get; set; }
    public DateTime JumpDate { get; set; }
    public JumpType JumpType { get; set; }
    public string Notes { get; set; }
    public User User { get; set; }
    public bool WithCutaway { get; set; }
}

Autres entités :

  • Aircraft : Données des aéronefs
  • User : Utilisateurs (avec authentification)
  • DropZone : Zones de parachute (parachute drops)
  • Gear : Équipement
  • JumpType : Types de sauts
  • Tunnel : Données de tunnels
  • TunnelFlight : Vols de tunnel
  • CacheType : Types de cache

User (avec authentification)

public class User
{
    public string Email { get; set; }
    public string FirstName { get; set; }
    public int Id { get; set; }
    public bool IsAdmin { get; set; }
    public string Language { get; set; }
    public string LastName { get; set; }
    public string Login { get; set; }
    public string Password { get; set; }
}

4.2 Modèles de Statistiques

Des entités dédiées pour les statistiques :

  • Statistic - Statistiques générales
  • StatsByAircraft - Statistiques par aéronef
  • StatsByDz - Statistiques par zone de parachute
  • StatsByGear - Statistiques par équipement
  • StatsByJumpType - Statistiques par type de saut
  • StatsByYear - Statistiques par année
  • StatsByYearByJumpType - Statistiques croisées année/type
  • StatsForLastMonthByDz - Statistiques du dernier mois
  • StatsForLastYearByDz - Statistiques de l'année dernière

5. Services de Business Logic (skydiveLogs-api.DomainBusiness)

5.1 Services Disponibles

Chaque service implémente une interface dans Interfaces :

Services CRUD

  • AircraftService - Gestion des aéronefs
  • DropZoneService - Gestion des zones de parachute
  • GearService - Gestion de l'équipement
  • JumpService - Gestion des sauts (principal)
  • JumpTypeService - Gestion des types de sauts
  • TunnelService - Gestion des tunnels
  • TunnelFlightService - Gestion des vols de tunnel
  • UserImageService - Gestion des images utilisateurs
  • UserService - Gestion des utilisateurs

Services de Cache

  • CacheService - Gestion du cache
  • IdentityService - Gestion de l'identité/authentification

Services d'Initialisation

  • InitDbService - Initialisation de la base de données

Services Statistiques

  • StatsService - Statistiques générales
  • StatsByAircraftService - Par aéronef
  • StatsByDzService - Par zone de parachute
  • StatsByGearService - Par équipement
  • StatsByJumpTypeService - Par type de saut
  • StatsByYearService - Par année
  • StatsByYearByJumpTypeService - Croisé année/type
  • StatsForLastMonthByDzService - Dernier mois
  • StatsForLastMonthByJumpTypeService - Dernier mois
  • StatsForLastYearByDzService - Dernière année
  • StatsForLastYearByJumpTypeService - Dernière année

5.2 Implémentations de Services (ex: JumpService)

Les services implémentent la logique métier et utilisent les repositories :

public class JumpService : IJumpService
{
    private readonly IJumpRepository _jumpRepository;
    private readonly IMapper _mapper;
    
    public void AddNewJump(...) { ... }
    public void DeleteJumpById(int id) { ... }
    public IEnumerable<Jump> GetAllJumps() { ... }
    public Jump GetJumpById(int id) { ... }
    public Jump GetJumpByUserAndDate(...) { ... }
    public int GetJumpCount() { ... }
    public IEnumerable<Jump> GetJumpsByIndexes(...) { ... }
    public Jump UpdateJump(int id, Jump jump) { ... }
}

6. Répositories (skydiveLogs-api.DomainService et Infrastructure)

6.1 Couche DomainService

Contient uniquement les interfaces IxxxRepository qui définissent le contrat d'accès aux données.

6.2 Couche Infrastructure

Implémente concrètement les repositories avec LiteDB (base de données fichier NoSQL) :

public class JumpRepository : IJumpRepository
{
    private readonly IDataProvider _dataProvider;
    private readonly IRepository<Jump> _jumpCollection;
    
    // Implémentation concrète
}

LiteDbProvider est utilisé comme fournisseur de données pour l'accès au fichier LiteDB.

7. Gestion des Données (Data)

7.1 Structure du Folder Data

skydiveLogs-api/Data/
├── Aircraft/
├── DropZone/
├── FavoriteDropZone/
├── Gear/
├── Image/
├── Jump/
├── JumpType/
├── StatsByAircraft/
├── StatsByDz/
├── StatsByGear/
├── StatsByJumpType/
├── StatsByYear/
├── StatsByYearByJumpType/
├── StatsForLastMonthByDz/
├── StatsForLastMonthByJumpType/
├── StatsForLastYearByDz/
├── StatsForLastYearByJumpType/
├── Tunnel/
├── TunnelFlight/
└── User/

Chaque dossier correspond à une collection LiteDB.

7.2 Contrats de Données (DataContract)

Les fichiers DataContract contiennent les DTOs (Data Transfer Objects) :

Requête (Req)

  • AircraftReq, DropZoneReq, GearReq, JumpReq, JumpTypeReq
  • UserReq, TunnelFlightReq, ImageReq

Réponse (Resp)

  • AircraftResp, AircraftSimpleResp, DropZoneResp, DropZoneSimpleResp
  • GearResp, JumpResp, JumpListResp, JumpTypeResp
  • UserResp, TunnelResp, TunnelFlightResp, ImageResp
  • StatisticResp, StatisticForChartResp
  • SimpleSummaryResp

Statistiques

  • StatsForLastMonthByDzResp
  • StatsForLastYearByDzResp

8. Mappage avec AutoMapper

8.1 Configuration AutoMapper

Le fichier Mapper contient le profile d'AutoMapper pour mapper entre :

  • Domain entities (Aircraft, User, Jump, etc.)
  • DTOs (AircraftResp, UserResp, JumpResp, etc.)
public class ModelProfile : Profile
{
    public ModelProfile()
    {
        // Configuration des mappages
        CreateMap<User, UserResp>();
        CreateMap<Aircraft, AircraftResp>();
        CreateMap<Jump, JumpResp>();
        // ... etc
    }
}

8.2 Utilisation dans les Contrôleurs

public JumpListResp Get()
{
    var tmp = _jumpService.GetAllJumps();
    var result = new JumpListResp
    {
        Rows = _mapper.Map<IEnumerable<JumpResp>>(tmp),
        Count = tmp.Count()
    };
    return result;
}

9. Authentification JWT

9.1 Configuration JWT (Startup.cs)

var jwtSection = Configuration.GetSection("JWT");
services.Configure<JwtSettings>(jwtSection);

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = jwtSettings.Issuer,
            ValidAudience = jwtSettings.Issuer,
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(jwtSettings.Passphrase))
        };
    });

9.2 Token Generation (UserController)

private string CreateToken(UserResp foundUser)
{
    var key = new SymmetricSecurityKey(
        Encoding.UTF8.GetBytes(_jwtConf.Passphrase));
    var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
        issuer: _jwtConf.Issuer,
        audience: _jwtConf.Issuer,
        expires: DateTime.Now.AddDays(1),
        signingCredentials: credentials,
        claims: new Claim[]
        {
            new Claim(ClaimTypes.Name, foundUser.Login),
            new Claim(ClaimTypes.UserData, foundUser.Id.ToString()),
            new Claim(ClaimTypes.Email, foundUser.Email),
            new Claim(ClaimTypes.Role, foundUser.Roles),
            new Claim("Language", foundUser.Language ?? "")
        });

    return new JwtSecurityTokenHandler().WriteToken(token);
}

10. Endpoints API Disponibles

10.1 Routes par Contrôleur

/api/Jump

  • GET /api/Jump - Liste tous les sauts
  • GET /api/Jump/{id} - Get par ID
  • GET /api/Jump/{beginJumpIndex}/{endJumpIndex} - Pagination
  • POST /api/Jump - Créer un saut
  • PUT /api/Jump/{id} - Mettre à jour
  • DELETE /api/Jump/{id} - Supprimer

/api/User

  • GET /api/User/AlwaysLogin - Vérification connexion
  • POST /api/User/Authenticate - Authentification
  • POST /api/User - Créer un utilisateur

/api/Aircraft

  • GET /api/Aircraft - Liste
  • GET /api/Aircraft/{id} - Get
  • GET /api/Aircraft/GetSimple - Liste simplifiée
  • POST /api/Aircraft - Créer
  • PUT /api/Aircraft/{id} - Mettre à jour
  • DELETE /api/Aircraft/{id} - Supprimer

/api/DropZone

  • GET /api/DropZone - Liste
  • GET /api/DropZone/{id} - Get
  • GET /api/DropZone/GetSimple - Liste simplifiée
  • POST /api/DropZone - Créer
  • PUT /api/DropZone/{id} - Mettre à jour
  • DELETE /api/DropZone/{id} - Supprimer
  • PUT /api/DropZone/AddToFavorite/{id} - Ajouter aux favoris
  • PUT /api/DropZone/RemoveToFavorite/{id} - Retirer des favoris

/api/Gear

  • GET /api/Gear - Liste
  • GET /api/Gear/{id} - Get
  • POST /api/Gear - Créer
  • PUT /api/Gear/{id} - Mettre à jour
  • DELETE /api/Gear/{id} - Supprimer

/api/JumpType

  • GET /api/JumpType - Liste
  • GET /api/JumpType/tunnel - Types pour tunnel
  • GET /api/JumpType/{id} - Get
  • POST /api/JumpType - Créer
  • PUT /api/JumpType/{id} - Mettre à jour
  • DELETE /api/JumpType/{id} - Supprimer

/api/Tunnel

  • GET /api/Tunnel - Liste
  • GET /api/Tunnel/{id} - Get

/api/TunnelFlight

  • Routes pour gestion des vols tunnel

/api/Image

  • GET /api/Image - Liste
  • GET /api/Image/{id} - Get
  • POST /api/Image - Créer
  • PUT /api/Image/{id} - Mettre à jour
  • DELETE /api/Image/{id} - Supprimer

/api/Stats

  • GET /api/Stats/ByAircraft - Stats par aéronef
  • GET /api/Stats/ByDz - Stats par zone
  • GET /api/Stats/ByGear - Stats par équipement
  • GET /api/Stats/ByJumpType - Stats par type
  • GET /api/Stats/ByYear - Stats par année
  • GET /api/Stats/ByYearByJumpType - Stats croisées
  • GET /api/Stats/ForLastMonth - Stats du mois dernier
  • GET /api/Stats/ForLastYear - Stats de l'année dernière
  • GET /api/Stats/Simple - Résumé simple
  • GET /api/Stats/Reset - Réinitialiser les stats

11. Gestion de Configuration

11.1 Fichiers appsettings

Les configurations sont stockées dans :

  • appsettings.json - Configuration par défaut
  • appsettings.Development.json - Configuration de développement
  • appsettings.Release.json - Configuration de production

11.2 Sections de Configuration

  • JWT - Configuration JWT (issuer, passphrase)
  • Cors - Configuration CORS (frontUrl)
  • ConnectionStrings - Connexion LiteDB (Filename)

12. Initialisation de la Base de Données

Le fichier CheckAndInitDb dans Startup.cs s'assure que :

  1. Le fichier LiteDB existe
  2. Si non, InitDbService.GenerateDb() crée la structure
  3. Si oui, InitDbService.Update() met à jour la structure

13. Bonnes Pratiques Observées

13.1 Séparation des Responsabilités

  • Les contrôleurs ne font que manipuler les requêtes/réponses
  • La logique métier est dans les services
  • L'accès aux données est dans les repositories

13.2 Sécurité

  • Authentification JWT
  • Autorisation par rôle (admin flag)
  • Validation des tokens
  • HSTS en production

13.3 Gestion des Erreurs

  • Développement avec UseDeveloperExceptionPage()
  • Production avec HSTS
  • Gestion des erreurs via services

13.4 Performance

  • Pagination des listes (par index)
  • Cache avec CacheService
  • AutoMapper pour éviter le code répétitif

14. Conclusion

L'API SkydiveLogs est une application C# robuste et bien structurée, utilisant :

  • ASP.NET Core MVC avec API
  • LiteDB comme base de données fichier
  • JWT pour l'authentification
  • AutoMapper pour le mappage
  • Injection de dépendances via IocService

L'architecture en couches assure une maintenabilité et une extensibilité optimales pour une application de journalisation de parachutisme.