Les sept packages .NET

Les sept packages ci-dessous sont disponibles sur NuGet.org en version 0.2.10. Conservez la même version pour ces packages dans chaque application.

Les exemples de bibliothèques utilisent 0.2.10 dans des projets .NET 10 et prennent aussi en charge .NET 8 et .NET 9. L'outil echo-mock nécessite .NET 10. Installer un package ne suffit pas à activer les mocks ni à valider les contrats.

Avant d'exécuter un exemple réseau, configurez GAPFY_ECHO_BASE_ADDRESS avec l'adresse de base de votre API Echo, barre finale comprise, et GAPFY_ECHO_API_KEY via l'environnement ou votre coffre de secrets. Utilisez l'adresse de l'API, pas l'URL publique du mock. Les nouvelles clés se créent dans Applications de Maestro, fonction d'Echo Pro et Pro AI qui nécessite Echo/ManageHosting ; l'administrateur de l'organisation reçoit cette autorisation par défaut avec un forfait payant et peut l'attribuer à un autre rôle. Le flux de règles est GET api/echo/mock/rules sur l'adresse de base configurée. Sans clé, l'endpoint renvoie 401. Il renvoie 403 si la clé n'a pas le scope ServeMocks ou si l'organisation n'a pas d'abonnement Echo payant en vigueur.

Gapfy.Echo.Contracts

Publie une version d'un contrat fourni par votre application. Créez d'abord le contrat et sa liaison Provides dans Maestro, créez une clé avec PublishOwnedContracts et définissez GAPFY_ECHO_CONTRACT_ID. Enregistrez un document de contrat Echo de l'éditeur sous orders.echo.json dans le répertoire de travail du processus. Il faut le document Echo, pas une réponse d'exemple ni un JSON Schema non converti.

dotnet new console -n EchoContractsDemo -f net10.0
dotnet add EchoContractsDemo package Gapfy.Echo.Contracts --version 0.2.10
using System.Net.Http.Headers;
using Gapfy.Echo.Contracts;

string Required(string name) =>
    Environment.GetEnvironmentVariable(name)
    ?? throw new InvalidOperationException($"Set {name}.");

using var http = new HttpClient
{
    BaseAddress = new Uri(Required("GAPFY_ECHO_BASE_ADDRESS"))
};
http.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue("Bearer", Required("GAPFY_ECHO_API_KEY"));

var publisher = new EchoContractPublicationClient(http);
var documentJson = await File.ReadAllTextAsync("orders.echo.json");
var publication = await publisher.PublishAsync(
    Guid.Parse(Required("GAPFY_ECHO_CONTRACT_ID")), documentJson);

Console.WriteLine(publication.AssignedVersion.Version);
Console.WriteLine(publication.Created);

Le package expose aussi le codec, le validateur et les moteurs d'inférence et d'évaluation des contrats. Le résultat de publication contient Changes avec les verdicts consommateur et fournisseur. Un verdict incompatible décrit une publication déjà terminée ; il ne l'annule pas. Un contenu identique peut renvoyer Created = false avec une version existante.

Gapfy.Echo.Testing

Vérifie les contrats consommés par l'application avec une clé ReadBoundContracts. L'appel lève une exception en cas de changement incompatible ; vous pouvez donc le placer dans votre framework de tests habituel. Cet exemple exige une réponse du service distant au lieu d'autoriser une réussite hors ligne.

dotnet new console -n EchoTestingDemo -f net10.0
dotnet add EchoTestingDemo package Gapfy.Echo.Testing --version 0.2.10
using Gapfy.Echo.Testing;

var echo = GapfyEchoValidation.Create(new GapfyEchoValidationOptions
{
    RequireRemote = true
});

await echo.Contracts.ValidateAsync();

Lors de la première exécution locale réussie, le package crée des instantanés EchoContracts à côté du projet. Vérifiez-les et ajoutez-les dans un commit. La CI refuse de créer les instantanés manquants. Sans RequireRemote = true, un service inaccessible peut produire une réussite hors ligne avec les instantanés du dépôt ; le rapport précise ce qui n'a pas été vérifié. Cela ne vérifie ni le contrat distant actuel ni l'API en cours d'exécution. Acceptez les changements d'instantanés volontairement sur un poste de travail, jamais automatiquement en CI.

Utilisez CheckAsync() pour obtenir le rapport sans exception, ou Only("partner-orders") pour vérifier certaines liaisons. Une sélection inconnue échoue au lieu de ne rien vérifier. Après vérification sur un poste de travail, AcceptAsync("partner-orders") met à jour une référence et AcceptAllAsync() les met toutes à jour ; la CI refuse cette acceptation. Activez TreatWarningsAsErrors pour traiter les avertissements comme des échecs et déclarez UnmappedMemberHandlingDisallow ou ExhaustiveStatusHandling si ces conditions concernent votre consommateur.

Gapfy.Echo.Mock.Client

Intercepte les appels sortants uniquement pour les HttpClient créés par la fabrique que vous activez. Cet exemple expose /probe et appelle l'URL réelle de PARTNER_API_URL avec le client activé. Définissez DOTNET_ENVIRONMENT=Development en local et fournissez une clé ServeMocks. Récupérer les règles fait partie d'Echo Pro et Pro AI ; un mock sur le bureau dans Free n'a pas besoin de ce package.

dotnet new web -n EchoMockClientDemo -f net10.0
dotnet add EchoMockClientDemo package Gapfy.Echo.Mock.Client --version 0.2.10
using Gapfy.Echo.Mock.Client;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEchoMock(x =>
{
    x.ApiKey = builder.Configuration["GAPFY_ECHO_API_KEY"];
    x.RuleServiceUri = new Uri(
        builder.Configuration["GAPFY_ECHO_BASE_ADDRESS"]
        ?? throw new InvalidOperationException("Set GAPFY_ECHO_BASE_ADDRESS."));
});
builder.Services.AddHttpClient("partner").AddEchoMockInterception();

var app = builder.Build();

app.MapGet("/probe", async (IHttpClientFactory factory) =>
{
    var target = app.Configuration["PARTNER_API_URL"]
        ?? throw new InvalidOperationException("Set PARTNER_API_URL.");
    return await factory.CreateClient("partner").GetStringAsync(target);
});

app.Run();

Les règles statiques et de contrat peuvent répondre dans votre application. Les réponses de contrat sont générées par Gapfy.Echo.Contracts et prennent en charge X-Echo-Scenario et X-Echo-Seed. Un contrat absent ou invalide, ou un échec de génération, renvoie 502 application/problem+json sans appeler le service réel. Les appels sans correspondance et ceux précédant le premier chargement des règles continuent vers le service réel. Si l'organisation perd le forfait payant, l'actualisation des règles renvoie 403 et écrit un avertissement, mais l'application continue à fonctionner. Les règles déjà chargées, y compris depuis une copie locale, peuvent continuer à intercepter ; sans règles, les appels passent au service réel. Un HttpClient créé manuellement, un canal gRPC ou un SDK avec son propre transport n'est pas intercepté. Le package ne peut pas être activé dans Production ou Prod ; les autres environnements hors Development exigent une confirmation explicite.

Gapfy.Echo.Mock.Server

Ajoute un middleware de mocks à votre API ASP.NET Core avec une clé ServeMocks. Récupérer les règles fait partie d'Echo Pro et Pro AI. Ici, /health reste un endpoint réel. Les routes que votre API n'implémente pas encore peuvent répondre à partir des règles Echo. Placez le middleware après le routage et avant l'exécution des endpoints, comme dans cet exemple avec WebApplication.

dotnet new web -n EchoMockServerDemo -f net10.0
dotnet add EchoMockServerDemo package Gapfy.Echo.Mock.Server --version 0.2.10
using Gapfy.Echo.Mock.Server;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEchoMock(x =>
{
    x.ApiKey = builder.Configuration["GAPFY_ECHO_API_KEY"];
    x.BaseAddress = new Uri(
        builder.Configuration["GAPFY_ECHO_BASE_ADDRESS"]
        ?? throw new InvalidOperationException("Set GAPFY_ECHO_BASE_ADDRESS."));
});

var app = builder.Build();

app.MapEchoMock();
app.MapGet("/health", () => Results.Ok(new { status = "ok" }));

app.Run();

Les routes implémentées et les requêtes sans correspondance continuent vers votre API. Les règles statiques renvoient les corps enregistrés ; les règles de contrat génèrent les réponses à partir du document. Utilisez X-Echo-Scenario pour choisir un scénario enregistré et X-Echo-Seed pour reproduire les valeurs générées. Un contrat invalide ou un échec de génération renvoie 502 au lieu d'appeler le code réel. Mock.Server s'active hors Production par défaut ; Production exige l'option explicite EnableInProduction. Sans règles chargées, les requêtes continuent normalement. Un échec d'actualisation conserve les dernières règles en cache.

Si l'interception cesse de fonctionner alors que la configuration semble correcte, vérifiez l'abonnement Echo de votre organisation et le scope ServeMocks avant de chercher une erreur dans votre code. Créer et essayer des mocks sur le bureau et travailler avec des contrats dans Maestro reste compris dans Free ; publier sur le service public et charger les règles pour ces deux packages nécessite Echo Pro ou Pro AI.

Gapfy.Echo.ApiExplorer

Ajoute Echo API Explorer à votre application ASP.NET Core. Consultez ses endpoints HTTP et descriptions OpenAPI, préparez une requête et examinez la réponse dans l'application. Vous pouvez choisir des réponses réelles ou des mocks Echo par controller ou endpoint, y compris pour des opérations déjà implémentées.

dotnet new web -n EchoExplorerDemo -f net10.0
dotnet add EchoExplorerDemo package Gapfy.Echo.ApiExplorer --version 0.2.10
using Gapfy.Echo.ApiExplorer;
using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication("Application")
    .AddCookie("Application", x => x.LoginPath = "/account/login");
builder.Services.AddAuthorization(x =>
{
    x.AddPolicy("Echo.View", x => x.RequireAuthenticatedUser()
        .RequireRole("EchoViewer", "EchoDeveloper", "EchoAdministrator"));
    x.AddPolicy("Echo.Execute", x => x.RequireAuthenticatedUser()
        .RequireRole("EchoDeveloper", "EchoAdministrator"));
    x.AddPolicy("Echo.Session", x => x.RequireAuthenticatedUser()
        .RequireRole("EchoDeveloper", "EchoAdministrator"));
    x.AddPolicy("Echo.Instance", x => x.RequireAuthenticatedUser()
        .RequireRole("EchoAdministrator"));
});
builder.Services.AddEchoDeveloperUI(builder.Configuration.GetSection("Echo"), x =>
{
    x.ApplicationName = "Orders.API";
    x.UI.RoutePrefix = "/tools/echo";
    x.UI.ManageSessionPolicy = "Echo.Session";
    x.UI.ManageInstancePolicy = "Echo.Instance";
});

var app = builder.Build();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEchoDeveloperUI();
app.MapEchoDeveloperUI();
app.MapGet("/api/orders", () => Results.Ok(new[] { new { id = 1 } }))
    .RequireAuthorization()
    .WithEchoMocking();
app.Run();

Cet exemple contient l'enregistrement complet. Il attend que la route de connexion de votre application, /account/login, émette le cookie Application avec les rôles nécessaires. Reliez cet enregistrement à votre authentification et à vos autorisations existantes ; le package ne crée pas de comptes et n'accorde aucun accès. Configurez Echo:ApiBaseAddress et Echo:ApiKey dans votre fournisseur de configuration protégé avec une clé ServeMocks. Après connexion, ouvrez /tools/echo à l'adresse de l'application. L'hôte choisit les environnements qui activent le panneau. Conservez l'autorisation métier avant UseEchoDeveloperUI ; les endpoints Minimal API nécessitent WithEchoMocking().

Choisir la portée avant d'appliquer

  1. Commencez par Ma session pour essayer un changement depuis votre exécuteur du panneau. Les autres clients continuent à utiliser le profil de l'instance.
  2. Choisissez un controller ou un endpoint, sélectionnez le serveur mock et la route, puis un scénario s'il en existe. Le choix de l'endpoint prime sur celui du controller ; l'héritage reprend le choix supérieur.
  3. Appliquez le profil, envoyez une requête depuis l'exécuteur et examinez le résultat. Sélectionner un serveur ou changer d'onglet n'applique pas le brouillon.
  4. Choisissez Toute l'instance si le changement doit affecter tous les clients de cette instance. Il faut l'autorisation de gestion de l'instance et confirmer le profil en attente.

Les profils personnels expirent et deviennent invalides lorsque la configuration de référence de l'instance change. Rechargez et vérifiez le nouvel état lorsque cela est demandé. Un mock sélectionné indisponible produit une erreur ; Echo n'exécute pas silencieusement le code réel. L'authentification et les filtres précédant le handler restent en vigueur ; le code à l'intérieur du handler remplacé ne s'exécute pas.

L'exécuteur accepte des paramètres, en-têtes, corps et identifiants. Se connecter au panneau et authentifier la requête sont deux actions distinctes. L'hôte peut activer une connexion OpenID Connect dans le navigateur ou une courte session Bearer avec sa validation de tokens existante ; ce sont des alternatives. Les tokens de session restent en mémoire serveur, expirent et disparaissent au redémarrage. La connexion par navigateur nécessite HTTPS. Le cookie du panneau n'authentifie pas les appels ordinaires à l'application.

L'interface propose sept langues et conserve le choix du navigateur. Les descriptions de l'API, noms de champs JSON et payloads gardent leur contenu d'origine. L'hôte peut limiter les endpoints visibles et activer l'isolation par organisation ; dans ce mode, les changements d'instance concernent uniquement l'organisation authentifiée. Le package actuel prend en charge HTTP et ne fournit pas d'API Explorer pour gRPC.

Gapfy.Echo.Offline

Conserve une configuration de mocks vérifiée dans un snapshot portable pour exécuter des tests sans contacter Echo. Le snapshot contient la révision du profil, les endpoints HTTP sélectionnés, les règles et contrats complets, les scénarios et la seed. Il ne contient ni la clé d'application Echo ni les identifiants de l'exécuteur.

Exportez le profil de l'instance depuis API Explorer avec l'autorisation de gestion de l'instance. Utilisez ensuite echo-mock export, ci-dessous, pour récupérer les règles sélectionnées pendant que vous êtes connecté. La bibliothèque lit et valide le fichier obtenu :

dotnet new console -n EchoOfflineDemo -f net10.0
dotnet add EchoOfflineDemo package Gapfy.Echo.Offline --version 0.2.10
using Gapfy.Echo.Offline;

var snapshot = await EchoOfflineSnapshotCodec.ReadAsync("echo.snapshot.json");
EchoOfflineSnapshotCodec.Validate(snapshot);
Console.WriteLine(snapshot.ContentHash);

La validation vérifie le hash du contenu, les contrats et la couverture complète des routes avant l'exécution. SHA-256 détecte les modifications du snapshot ; il n'identifie pas son auteur et n'accorde aucun accès. Traitez les corps de réponse du fichier comme des données de test pouvant nécessiter un accès restreint. Un snapshot aux règles incomplètes ou sans sélection de mock ne peut pas être exécuté.

L'application qui importe le snapshot via API Explorer doit configurer explicitement le mode hors ligne et correspondre aux identités d'application, de workspace, de profil et d'endpoints. Un snapshot d'organisation doit aussi correspondre à cette organisation. Les profils importés sont en lecture seule et n'actualisent pas de catalogue distant.

Gapfy.Echo.Mock.Runner

Installe la commande echo-mock pour exécuter des snapshots HTTP préparés. Elle est indépendante de gapfy-echo, qui exécute des collections et des chaînes.

dotnet tool install --global Gapfy.Echo.Mock.Runner --version 0.2.10
echo-mock export --profile echo.mock.json --server https://api.example.test/ --key-env ECHO_API_KEY --output echo.snapshot.json --seed 17
echo-mock validate --snapshot echo.snapshot.json --report validation.json
echo-mock run --snapshot echo.snapshot.json --report execution.json --timeout 300 -- dotnet Tests.dll --minimum-expected-tests 1

Remplacez l'adresse d'exemple par l'adresse configurée de l'API Echo. Définissez ECHO_API_KEY dans l'environnement ou les secrets du CI ; la commande d'export reçoit le nom de la variable, sans passer le secret comme argument. La clé nécessite ServeMocks et l'accès au flux payant de règles. Préparez l'outil, le runtime .NET et les tests compilés avant la phase hors ligne.

run valide le snapshot, ouvre un listener privé sur loopback et lance la commande après --. Utilisez la vraie commande de test du projet ; l'exemple attend une application de tests Microsoft.Testing.Platform déjà compilée et exige au moins un test. Le processus enfant reçoit ECHO_MOCK_BASE_ADDRESS et les paramètres Echo__Offline__*. Les consommateurs d'API Explorer utilisent le profil importé ; les consommateurs HTTP directs utilisent /servers/{serverId} suivi du chemin de la règle.

Une seed fixe stabilise les valeurs aléatoires. Les générateurs dépendant des dates peuvent encore varier dans le temps ; utilisez des dates constantes pour une répétition exacte. Les routes inconnues renvoient 404 au lieu de contacter un service réel. Le runner ne bloque pas le reste du trafic réseau de l'application testée.

Utilisez serve --snapshot echo.snapshot.json --port 0 --ready-file ready.json lorsqu'un autre processus doit gérer l'exécution. Le fichier de disponibilité et /_echo/ready identifient le snapshot validé. Une annulation ou un timeout arrête le listener et le processus enfant du runner. Le rapport JSON enregistre le hash, les compteurs de routes et le résultat de l'enfant, sans corps de requête ni identifiants. Les codes de sortie sont 0 pour le succès, 2 pour une entrée invalide, 3 pour un échec d'exécution ou une route sans correspondance et 130 pour une annulation ; un enfant en échec conserve son propre code de sortie.

Choisir la bonne voie