Die sieben .NET-Pakete

Die folgenden sieben Pakete sind auf NuGet.org in Version 0.2.10 verfügbar. Verwende innerhalb einer Anwendung dieselbe Version dieser Pakete.

Die Bibliotheksbeispiele verwenden 0.2.10 in .NET-10-Projekten und unterstützen auch .NET 8 und .NET 9. Das Tool echo-mock benötigt .NET 10. Die Installation allein aktiviert keine Mocks und prüft keine Verträge.

Bevor du ein Netzwerkbeispiel ausführst, setze GAPFY_ECHO_BASE_ADDRESS auf die Basisadresse deiner Echo-API einschließlich abschließendem Schrägstrich und GAPFY_ECHO_API_KEY über die Umgebung oder deinen Secret-Speicher. Verwende die API-Adresse, nicht die öffentliche Mock-URL. Schlüssel werden unter Anwendungen in Maestro ausgestellt. Dazu brauchst du Echo Pro oder Pro AI und die Berechtigung Echo/ManageHosting, die der Organisationsadministrator in einem bezahlten Tarif standardmäßig erhält und einer anderen Rolle geben kann. Der Regelfeed liegt unter GET api/echo/mock/rules auf der konfigurierten API-Basisadresse. Ohne Schlüssel antwortet der Endpunkt mit 401; ohne den erforderlichen Scope ServeMocks oder ohne gültigen bezahlten Echo-Tarif mit 403.

Gapfy.Echo.Contracts

Veröffentlicht eine Version eines Vertrags, den deine Anwendung anbietet. Erstelle zuerst den Vertrag und seine Provides-Bindung in Maestro, erstelle einen Schlüssel mit PublishOwnedContracts und setze GAPFY_ECHO_CONTRACT_ID. Speichere ein Echo-Vertragsdokument aus dem Editor als orders.echo.json im Arbeitsverzeichnis des Prozesses. Es muss das Echo-Dokument sein, keine Beispielantwort und kein unkonvertiertes JSON Schema.

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);

Das Paket stellt auch den Codec, den Validator sowie die Inferenz- und Auswertungsmodule für Verträge bereit. Das Veröffentlichungsergebnis enthält Changes mit Bewertungen für Verbraucher und Anbieter. Eine inkompatible Bewertung beschreibt eine bereits abgeschlossene Veröffentlichung und macht sie nicht rückgängig. Identischer Inhalt kann Created = false mit einer vorhandenen Version zurückgeben.

Gapfy.Echo.Testing

Prüft die von der Anwendung konsumierten Verträge mit einem ReadBoundContracts-Schlüssel. Bei einer inkompatiblen Änderung wirft der Aufruf eine Ausnahme. Du kannst ihn daher in deinem bestehenden Testframework verwenden. Dieses Beispiel verlangt eine Antwort des entfernten Dienstes und erlaubt keinen erfolgreichen Offline-Lauf.

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();

Beim ersten erfolgreichen lokalen Lauf erstellt das Paket EchoContracts-Momentaufnahmen neben dem Projekt. Prüfe sie und nimm sie in einen Commit auf. Die CI erstellt keine fehlenden Momentaufnahmen. Ohne RequireRemote = true kann ein unerreichbarer Dienst zu einem erfolgreichen Offline-Lauf mit den gespeicherten Momentaufnahmen führen. Der Bericht erklärt, was nicht geprüft wurde. Das prüft weder den heutigen entfernten Vertrag noch die laufende API. Akzeptiere Änderungen bewusst auf einem Arbeitsplatzrechner, nie automatisch in der CI.

Mit CheckAsync() erhältst du den Bericht ohne Exception; Only("partner-orders") prüft ausgewählte Bindungen. Eine unbekannte Auswahl schlägt fehl, statt nichts zu prüfen. Nach der Prüfung auf einem Arbeitsplatzrechner aktualisiert AcceptAsync("partner-orders") einen Vergleichsstand und AcceptAllAsync() alle; CI verweigert diese Übernahme. Aktiviere TreatWarningsAsErrors, um Warnungen als Fehler zu behandeln, und setze UnmappedMemberHandlingDisallow oder ExhaustiveStatusHandling, wenn diese Bedingungen für deinen Verbraucher gelten.

Gapfy.Echo.Mock.Client

Fängt ausgehende Aufrufe nur für ausdrücklich aktivierte HttpClient-Instanzen aus der Factory ab. Dieses Beispiel stellt /probe bereit und ruft die echte URL aus PARTNER_API_URL über den aktivierten Client auf. Setze für lokale Nutzung DOTNET_ENVIRONMENT=Development und hinterlege einen ServeMocks-Schlüssel. Das Laden der Mock-Regeln gehört zu Echo Pro und Pro AI. Ohne erfolgreich geladene Regeln fängt der Client nichts ab und ruft den echten Dienst auf; eine verweigerte Aktualisierung beendet deine Anwendung nicht.

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();

Statische Regeln und Vertragsregeln können innerhalb deiner Anwendung antworten. Gapfy.Echo.Contracts erzeugt die Vertragsantworten und unterstützt X-Echo-Scenario und X-Echo-Seed. Ein fehlender oder ungültiger Vertrag oder eine fehlgeschlagene Generierung liefert 502 application/problem+json, ohne den echten Dienst aufzurufen. Anfragen ohne Treffer und Aufrufe vor dem ersten Laden der Regeln laufen zum echten Dienst weiter. Manuell erstellte HttpClient-Instanzen, gRPC-Kanäle und SDKs mit eigenem Transport werden nicht abgefangen. In Production und Prod lässt sich das Paket nicht aktivieren. Andere Umgebungen außerhalb von Development verlangen eine ausdrückliche Bestätigung.

Gapfy.Echo.Mock.Server

Ergänzt deine ASP.NET-Core-API um Mock-Middleware mit einem ServeMocks-Schlüssel. Der Regelfeed gehört auch hier zu Echo Pro und Pro AI. Im Beispiel bleibt /health ein echter Endpunkt. Noch nicht implementierte Routen können anhand passender Echo-Regeln antworten. Platziere die Middleware nach dem Routing und vor der Endpunktausführung, wie hier mit WebApplication gezeigt. Ohne geladene Regeln startet deine API weiterhin und bearbeitet die Routen wie ohne Mock-Middleware.

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();

Implementierte Routen und Anfragen ohne Treffer laufen zu deiner API weiter. Statische Regeln liefern gespeicherte Antworttexte; Vertragsregeln erzeugen Antworten aus dem Vertragsdokument. Mit X-Echo-Scenario wählst du ein gespeichertes Szenario, mit X-Echo-Seed wiederholst du generierte Werte. Ein ungültiger Vertrag oder eine fehlgeschlagene Generierung liefert 502, statt den echten Handler aufzurufen. Mock.Server ist außerhalb von Production standardmäßig aktiv; Production erfordert die ausdrückliche Option EnableInProduction. Ohne geladene Regeln laufen Anfragen weiter. Eine fehlgeschlagene Aktualisierung behält die zuletzt gespeicherten Regeln.

Wenn die Interception bei richtiger Konfiguration ausbleibt, prüfe zuerst den Echo-Tarif deiner Organisation und den Scope des Schlüssels. Im Free-Tarif lässt sich kein neuer Anwendungsschlüssel ausstellen, und der Regelfeed verweigert auch einem zuvor ausgestellten Schlüssel den Zugriff. Mock.Client protokolliert den fehlgeschlagenen Abruf als Warnung, Mock.Server als Fehler; beide Anwendungen laufen weiter. Achtung: Bereits geladene oder auf dem Datenträger gespeicherte Regeln können weiterhin Mock-Antworten liefern, bis du den jeweiligen Cache leerst oder die Interception deaktivierst. Mocks auf dem Desktop und die Arbeit mit Verträgen in Maestro bleiben in Free verfügbar.

Gapfy.Echo.ApiExplorer

Ergänzt deine ASP.NET-Core-Anwendung um Echo API Explorer. Du kannst HTTP-Endpunkte und OpenAPI-Beschreibungen ansehen, eine Anfrage vorbereiten und die Antwort direkt in der Anwendung prüfen. Pro Controller oder Endpunkt wählst du echte Antworten oder Echo-Mocks, auch für bereits implementierte Operationen.

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();

Dieses Beispiel enthält die vollständige Registrierung. Es setzt voraus, dass die Anmelderoute deiner Anwendung unter /account/login das Cookie Application mit den benötigten Rollen ausstellt. Verbinde die Registrierung mit deiner vorhandenen Authentifizierung und deinen Berechtigungen; das Paket erstellt keine Konten und vergibt keinen Zugriff. Hinterlege Echo:ApiBaseAddress und Echo:ApiKey in deiner geschützten Konfiguration mit einem ServeMocks-Schlüssel. Öffne nach der Anmeldung /tools/echo an der Adresse deiner Anwendung. Der Host entscheidet, in welchen Umgebungen das Panel aktiv ist. Die fachliche Autorisierung bleibt vor UseEchoDeveloperUI; Minimal-API-Endpunkte benötigen WithEchoMocking().

Den Geltungsbereich vor dem Anwenden wählen

  1. Beginne mit Meine Sitzung, um eine Änderung über deinen Panel-Executor zu testen. Andere Clients verwenden weiterhin das Instanzprofil.
  2. Wähle einen Controller oder Endpunkt, den Mock-Server und die Route sowie gegebenenfalls ein Szenario. Die Auswahl am Endpunkt hat Vorrang vor der Controller-Auswahl; Vererbung übernimmt die übergeordnete Auswahl.
  3. Wende das Profil an, sende eine Anfrage aus dem Executor und prüfe das Ergebnis. Die Serverauswahl oder ein Tabwechsel wendet deinen Entwurf noch nicht an.
  4. Wähle Gesamte Instanz, wenn die Änderung alle Clients dieser Instanz betreffen soll. Dafür brauchst du die Berechtigung zur Instanzverwaltung und musst das ausstehende Profil bestätigen.

Persönliche Profile laufen ab und werden ungültig, wenn sich die zugrunde liegende Instanzkonfiguration ändert. Lade den Zustand dann neu und prüfe ihn. Ein nicht verfügbarer ausgewählter Mock führt zu einem Fehler; Echo ruft nicht stillschweigend den echten Handler auf. Authentifizierung und Filter vor dem Handler bleiben wirksam; Code innerhalb eines ersetzten Handlers läuft nicht.

Der Executor unterstützt Parameter, Header, Request-Bodies und Zugangsdaten. Panel-Anmeldung und Request-Authentifizierung sind getrennt. Der Host kann eine OpenID-Connect-Anmeldung im Browser oder eine kurze Bearer-Sitzung mit seiner bestehenden Tokenvalidierung aktivieren; diese Möglichkeiten sind Alternativen. Sitzungstokens bleiben im Serverspeicher, laufen ab und gehen beim Neustart verloren. Die Browseranmeldung erfordert HTTPS. Das Panel-Cookie authentifiziert keine gewöhnlichen Geschäftsaufrufe.

Die Oberfläche bietet sieben Sprachen und behält die Browserauswahl bei. API-Beschreibungen, JSON-Feldnamen und Payloads bleiben unverändert. Der Host kann sichtbare Endpunkte einschränken und Organisationen getrennt behandeln; in diesem Modus wirken Instanzänderungen nur auf die authentifizierte Organisation. Das aktuelle Paket unterstützt HTTP und bietet keinen gRPC API Explorer.

Gapfy.Echo.Offline

Speichert eine geprüfte Mock-Konfiguration in einem portablen Snapshot, damit Tests ohne Verbindung zu Echo laufen können. Der Snapshot enthält Profilrevision, ausgewählte HTTP-Endpunkte, vollständige Regeln und Verträge, Szenarien und Seed. Er enthält weder den Echo-Anwendungsschlüssel noch Zugangsdaten des Executors.

Exportiere das Instanzprofil aus API Explorer mit der Berechtigung zur Instanzverwaltung. Lade anschließend mit echo-mock export die ausgewählten Regeln, solange eine Verbindung besteht. Die Bibliothek liest und prüft die erzeugte Datei:

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);

Die Validierung prüft vor der Ausführung den Inhaltshash, die Verträge und die vollständige Routenabdeckung. SHA-256 erkennt Änderungen am Snapshot; es bestätigt weder dessen Autor noch Zugriffsrechte. Antworttexte in der Datei sind Testdaten, für die möglicherweise ein eingeschränkter Zugriff nötig ist. Ein Snapshot mit unvollständigen Regeln oder ohne Mock-Auswahl kann nicht ausgeführt werden.

Eine Anwendung, die den Snapshot über API Explorer importiert, muss den Offline-Modus ausdrücklich konfigurieren und mit den Kennungen für Anwendung, Workspace, Profil und Endpunkte übereinstimmen. Ein Organisationssnapshot muss zusätzlich zur Organisation passen. Importierte Profile sind schreibgeschützt und aktualisieren keinen entfernten Katalog.

Gapfy.Echo.Mock.Runner

Installiert den Befehl echo-mock zum Ausführen vorbereiteter HTTP-Snapshots. Er ist unabhängig von gapfy-echo, das Sammlungen und Ketten ausführt.

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

Ersetze die Beispieladresse durch die konfigurierte Adresse deiner Echo-API. Setze ECHO_API_KEY über die Umgebung oder den Secret-Speicher deines CI; der Exportbefehl erhält den Variablennamen, nicht den geheimen Wert als Argument. Der Schlüssel benötigt ServeMocks und Zugriff auf den kostenpflichtigen Regelfeed. Bereite Tool, .NET-Runtime und kompilierte Tests vor der Offline-Phase vor.

run validiert den Snapshot, öffnet einen privaten Loopback-Listener und startet den Befehl nach --. Verwende den tatsächlichen Testbefehl deines Projekts; das Beispiel erwartet eine kompilierte Microsoft.Testing.Platform-Testanwendung und verlangt mindestens einen Test. Der Kindprozess erhält ECHO_MOCK_BASE_ADDRESS und die Einstellungen Echo__Offline__*. API-Explorer-Verbraucher verwenden das importierte Profil; direkte HTTP-Verbraucher verwenden /servers/{serverId} und danach den Regelpfad.

Ein fester Seed stabilisiert Zufallswerte. Datumsabhängige Generatoren können sich weiterhin mit der Zeit ändern; verwende konstante Daten, wenn eine exakte Wiederholung nötig ist. Unbekannte Routen liefern 404, statt einen echten Dienst aufzurufen. Der Runner blockiert keinen sonstigen Netzwerkverkehr der getesteten Anwendung.

Verwende serve --snapshot echo.snapshot.json --port 0 --ready-file ready.json, wenn ein anderer Prozess den Lauf steuert. Die Bereitschaftsdatei und /_echo/ready nennen den validierten Snapshot. Abbruch oder Timeout beendet Listener und Kindprozess des Runners. Der JSON-Bericht enthält Hash, Routenzähler und Kindprozessergebnis, aber keine Request-Bodies oder Zugangsdaten. Die Exitcodes sind 0 für Erfolg, 2 für ungültige Eingaben, 3 für Laufzeitfehler oder nicht zugeordnete Routen und 130 für Abbruch; ein fehlgeschlagener Kindprozess behält seinen eigenen Exitcode.

Wähle den passenden Weg