Aller au contenu principal

Démarrage rapide

En 10 minutes : lecture, écriture et réception d'un webhook.

Prérequis : MCM.ApiProxy installé (Installation) + clé API configurée (Configuration).


1. Lire — premier appel​

Services/EmployeService.cs
using MCM.ApiProxy.Contracts;
using MCM.B2B.Contracts;

public class EmployeService(IEmployesClient employesClient, ILogger<EmployeService> logger)
{
public async Task<List<B2BEmployeItem>> GetAllEmployesAsync()
{
var result = await employesClient.GetAllEmployes();

if (result.IsError)
{
logger.LogError("Erreur récupération employés: {Error}", result.FirstError.Description);
return [];
}

return result.Value.ToList();
}

public async Task<B2BEmployeItem?> GetEmployeAsync(string idExterne)
{
var result = await employesClient.GetEmployeById(idExterne);
return result.IsError ? null : result.Value;
}
}
Program.cs
using MCM.ApiProxy;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMcmApiClient(builder.Configuration); // tous les clients en une seule fois
builder.Services.AddScoped<EmployeService>();

var app = builder.Build();
Controllers/EmployesController.cs
[ApiController]
[Route("api/[controller]")]
public class EmployesController(EmployeService service) : ControllerBase
{
[HttpGet]
public async Task<IActionResult> GetAll() => Ok(await service.GetAllEmployesAsync());

[HttpGet("{idExterne}")]
public async Task<IActionResult> GetById(string idExterne)
{
var e = await service.GetEmployeAsync(idExterne);
return e is null ? NotFound() : Ok(e);
}
}

2. Comprendre ErrorOr<T>​

Toutes les méthodes du SDK retournent ErrorOr<T>. Aucune ne lance d'exception sur erreur métier ou HTTP.

var result = await employesClient.GetEmployeById("EMP-123");

if (result.IsError)
{
var e = result.FirstError;
// e.Code → "Employe.NotFound"
// e.Description → "Aucun employé n'existe avec cet identifiant."
// e.Type → ErrorType.NotFound
// e.Metadata → { "Url": "…", "StatusName": "NotFound", … } selon l'erreur
return;
}

var employe = result.Value;
AspectErrorOrExceptions
PerformancePas de stack unwindingCoûteux à lancer
LisibilitéFlux expliciteFlux caché
Compilationresult.Value non accessible sans vérifier IsError (avec Match/pattern matching)Risque d'oublier le try

Référence complète des codes : catalogue d'erreurs. Patterns de gestion : Gestion des erreurs.


3. Écrire — créer un employé​

public async Task<bool> CreateEmployeAsync(B2BUpdateEmployeDto dto)
{
var result = await employesClient.AddEmploye(dto);

if (result.IsError)
{
logger.LogError("Échec création {Id}: [{Code}] {Desc}",
dto.IdExterne, result.FirstError.Code, result.FirstError.Description);
return false;
}

logger.LogInformation("Employé créé: {IdExterne}", dto.IdExterne);
return true;
}

// Appel
await CreateEmployeAsync(new B2BUpdateEmployeDto
{
IdExterne = "PERSON-123",
Prenom = "Alice",
Nom = "Tremblay",
Courriel = "alice@example.com",
NoMembre = "NM-2026-001",
IdentifiantExterneEmployeur = "EMP001",
Matricule = "A123"
});

Pour un import groupé, ne bouclez pas sur AddEmploye. Utilisez ISyncClient.Sync — un seul appel pour des milliers d'employés. Voir Synchronisation des employés.


4. Recevoir un webhook​

Quand un événement métier intéressant se produit côté MCM (adhésion signée, liste électorale créée, …), MCM peut envoyer les données à votre application au lieu de vous obliger à les interroger périodiquement.

4.1 Configurer le récepteur​

appsettings.json
{
"McmApi": {
"BaseUrl": "https://mcm-dev.neosapiens.com/",
"ApiKey": "<votre-cle>",
"WebhookSecret": "<base64-fourni-par-mcm>"
}
}
Program.cs (suite)
using MCM.ApiProxy.Webhooks;
using MCM.B2B.Contracts.V2;
using MCM.B2B.Contracts.Webhooks;

builder.Services.AddMcmWebhookReceiver(builder.Configuration)
.AddHandler<AdhesionSigneeHandler, B2BAdhesionItemV2>(WebhookEventTypes.AdhesionSignee);

var app = builder.Build();

app.MapMcmWebhooks("/webhooks/mcm");

4.2 Écrire le handler​

Webhooks/AdhesionSigneeHandler.cs
using MCM.B2B.Contracts.V2;
using MCM.B2B.Contracts.Webhooks;

public class AdhesionSigneeHandler(ILogger<AdhesionSigneeHandler> logger)
: IMcmWebhookHandler<B2BAdhesionItemV2>
{
public Task HandleAsync(B2BWebhookPayload<B2BAdhesionItemV2> p, CancellationToken ct)
{
logger.LogInformation(
"Adhésion {Id} signée pour {Employe} (syndicat {Syndicat})",
p.Data.IdUniqueAdhesion, p.Data.EmployeIdExterne, p.Data.SyndicatIdExterne);
return Task.CompletedTask;
}
}

C'est tout. Le middleware fourni par le SDK :

  • valide la signature HMAC-SHA256 (X-MCM-Signature),
  • vérifie l'âge du timestamp (X-MCM-Timestamp, fenêtre 5 min),
  • désérialise typé vers B2BWebhookPayload<TData>,
  • résout votre handler depuis le DI.

Tester localement : exposez votre service via ngrok http 5050 et donnez l'URL à l'admin MCM. Détails : Webhooks.


5. Code complet (récapitulatif)​

Program.cs (complet)
using MCM.ApiProxy;
using MCM.ApiProxy.Webhooks;
using MCM.B2B.Contracts.V2;
using MCM.B2B.Contracts.Webhooks;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMcmApiClient(builder.Configuration);
builder.Services.AddScoped<EmployeService>();

builder.Services.AddMcmWebhookReceiver(builder.Configuration)
.AddHandler<AdhesionSigneeHandler, B2BAdhesionItemV2>(WebhookEventTypes.AdhesionSignee);

builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();
app.MapMcmWebhooks("/webhooks/mcm");

app.Run();

Prochaines étapes​


Voir un exemple complet​

L'application CLI MCM.ApiProxy.Cli couvre tous les clients du SDK avec un menu interactif (Spectre.Console). C'est la référence vivante pour explorer l'API.