Os quatro pacotes .NET

A fonte NuGet configurada tem de disponibilizar a versão 0.2.2 para estes comandos de instalação funcionarem.

Usa a versão 0.2.2 nos exemplos abaixo. Cada exemplo é um Program.cs completo num projeto .NET 10 separado. Os pacotes também incluem versões para .NET 8 e .NET 9. Instalar um pacote, por si só, não ativa mocks nem valida contratos.

Antes de executar um exemplo com rede, configura GAPFY_ECHO_BASE_ADDRESS com o endereço base da API do Echo, incluindo a barra final, e GAPFY_ECHO_API_KEY através do ambiente ou do cofre de segredos. Usa o endereço da API, não o URL público do mock. A versão correspondente da API tem de estar publicada: o feed de regras é GET api/echo/mock/rules. Um 404 nessa rota não significa que não existam regras.

Gapfy.Echo.Contracts

Publica uma versão de um contrato que a tua aplicação fornece. Cria primeiro o contrato e a associação Provides no Maestro, emite uma chave com PublishOwnedContracts e define GAPFY_ECHO_CONTRACT_ID. Guarda um documento de contrato Echo do editor como orders.echo.json na pasta de trabalho do processo. Tem de ser o documento Echo, não uma resposta de exemplo nem um JSON Schema por converter.

dotnet new console -n EchoContractsDemo -f net10.0
dotnet add EchoContractsDemo package Gapfy.Echo.Contracts --version 0.2.2
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);

O pacote também disponibiliza o codec, o validador e os motores de inferência e avaliação de contratos. O resultado da publicação inclui Changes, com veredictos para consumidor e fornecedor. Um veredicto incompatível descreve uma publicação já concluída; não a anula. Conteúdo idêntico pode devolver Created = false com uma versão existente.

Gapfy.Echo.Testing

Verifica os contratos consumidos pela aplicação com uma chave ReadBoundContracts. A chamada lança uma exceção perante uma alteração incompatível, pelo que podes colocá-la no teu framework de testes. Este exemplo exige resposta do serviço remoto em vez de permitir um resultado positivo offline.

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

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

await echo.Contracts.ValidateAsync();

Na primeira execução local com sucesso, o pacote cria retratos EchoContracts junto ao projeto. Revê-os e inclui-os num commit. O CI recusa criar retratos em falta. Sem RequireRemote = true, um serviço inacessível pode produzir um resultado positivo offline com os retratos do repositório; o relatório explica o que não foi verificado. Isso não verifica o contrato remoto de hoje nem a API em execução. Aceita alterações aos retratos deliberadamente numa máquina de trabalho, nunca automaticamente no CI.

Gapfy.Echo.Mock.Client

Interceta chamadas de saída apenas nos HttpClient criados pela factory que ativares. O exemplo expõe /probe e chama o URL real de PARTNER_API_URL pelo cliente ativado. Define DOTNET_ENVIRONMENT=Development para uso local e fornece uma chave ServeMocks.

dotnet new web -n EchoMockClientDemo -f net10.0
dotnet add EchoMockClientDemo package Gapfy.Echo.Mock.Client --version 0.2.2
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();

As regras estáticas podem responder localmente. As regras em modo contrato passam para o serviço real na versão 0.2.2. O mesmo acontece sem correspondência ou antes de carregar as primeiras regras. Um HttpClient criado manualmente, um canal gRPC ou um SDK com transporte próprio não é intercetado. O pacote não pode ser ativado em Production ou Prod; outros ambientes fora de Development exigem uma confirmação explícita.

Gapfy.Echo.Mock.Server

Adiciona middleware de mocks à tua API ASP.NET Core com uma chave ServeMocks. Neste exemplo, /health continua a ser um endpoint real. As rotas ainda não implementadas pela API podem responder com regras do Echo. Coloca o middleware depois do encaminhamento e antes da execução dos endpoints, como neste exemplo com WebApplication.

dotnet new web -n EchoMockServerDemo -f net10.0
dotnet add EchoMockServerDemo package Gapfy.Echo.Mock.Server --version 0.2.2
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();

O middleware deixa passar rotas implementadas e pedidos sem correspondência. Serve os corpos de resposta guardados e substituições de parâmetros do caminho; não avalia o documento de geração de contratos na versão 0.2.2. Fica ativo fora de Production por predefinição. Production exige a opção explícita EnableInProduction. Sem regras carregadas, deixa passar os pedidos; uma atualização falhada mantém as últimas regras em cache.

Escolhe o caminho certo