Offside

offside

Documentação do Offside

catch it before the whistle · English

NuGet Downloads CI License Frameworks

Erros de domínio como Result, não como exceções. O domínio devolve um Error; o ASP.NET Core mapeia isso para Problem Details (RFC 7807). As mensagens ficam em catálogos JSON, não em C#.

Prefere um guia navegável com diagramas de arquitetura? Visite a Wiki em português ou a Wiki em inglês.

Comece por aqui

Página O que cobre
Primeiros passos Instalar, registrar e devolver a primeira resposta Problem Details
Conceitos Error, ErrorCode, ErrorKind, Result, erro primário, catálogos, escape hatch
Guia de domínio Escrever código de domínio com Result<T>: factories, Custom, Bind/Map/Combine
Guia ASP.NET Core ToHttpResult / ToActionResult, escolha do status, formato da resposta, tratamento de 500
FluentValidation Mapear falhas do FluentValidation para Error / Result do Offside
FastEndpoints UseOffside, SendOffsideAsync, erros esperados no OpenAPI
Integração com MediatR Publicar erros de resultados como notificações, coletá-los por scope e tratar retries com segurança
Integração com Refit Transformar a falha de uma API externa em Error, sem try/catch em cada chamada
Application Insights Registrar erros de domínio como traces, com severidade e dimensões estáveis
OpenTelemetry Registrar erros de domínio via OpenTelemetry, para hosts com Azure.Monitor.OpenTelemetry ou exporter OTLP
Consultar erros de domínio Filtros Kusto em offside.code / offside.errorCode / offside.kind — não há {OriginalFormat}
Mensagens e culturas Formato do catálogo, fallback de cultura, interpolação de {token}
Guia de testes Asserções sobre Result, Error e catálogos de mensagens em testes
CLI offside init — skills de agente e templates de catálogo
Referência de API Todos os tipos e membros públicos, em uma página
FAQ Decisões de design e armadilhas comuns

O formato disso

// Domínio — não sabe nada sobre HTTP
public Result<Order> Get(string id)
{
    var order = _orders.Find(id);
    return order is null
        ? Result<Order>.Failure(Error.NotFound("order", id))
        : Result<Order>.Success(order);
}
// Endpoint — uma linha
app.MapGet("/orders/{id}", (string id, HttpContext http) => _orders.Get(id).ToHttpResult(http));
// Resposta — 404, application/problem+json
{
  "type": "https://httpstatuses.io/404",
  "title": "NotFound",
  "status": 404,
  "detail": "order '42' was not found.",
  "errorCode": "NOT_FOUND",
  "traceId": "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01",
  "errors": [
    { "code": "not_found", "errorCode": "NOT_FOUND", "kind": "NotFound", "detail": "order '42' was not found.", "field": null }
  ]
}

Pacotes

Pacote Versão Target frameworks Papel
Offside NuGet netstandard2.0, net8.0, net10.0 Error, ErrorKind, Result / Result<T>, resolver JSON, AddOffside
Offside.AspNetCore NuGet net8.0, net10.0 ToHttpResult / ToActionResult, Problem Details, AddOffsideAspNetCore
Offside.FluentValidation NuGet netstandard2.0, net8.0, net10.0 Falhas FluentValidation → Error / Result
Offside.FastEndpoint NuGet net8.0, net10.0 UseOffside, SendOffsideAsync, erros esperados no OpenAPI
Offside.AzureAppConfiguration NuGet netstandard2.0, net8.0, net10.0 Resolver dinâmico para catálogos carregados pelo Azure App Configuration
Offside.MediatR NuGet netstandard2.0, net8.0, net10.0 Notificações MediatR para resultados com falha e coletor scoped
Offside.Testing NuGet netstandard2.0, net8.0, net10.0 Asserções sobre Result, Error e catálogos, sem dependência de framework de teste
Offside.Refit NuGet netstandard2.0, net8.0, net10.0 Falhas do Refit vindas de API externa mapeadas para Error / Result
Offside.ApplicationInsights NuGet netstandard2.0, net8.0, net10.0 Erros de domínio registrados como traces do Application Insights
Offside.ApplicationInsights.MediatR NuGet netstandard2.0, net8.0, net10.0 Ponte que registra domain notifications publicadas como telemetria
Offside.Tool NuGet net8.0 offside init — skills de agente e templates de catálogo

O pacote core não tem dependência de ASP.NET nem de MediatR, então projetos de domínio podem referenciá-lo livremente.

Em outro lugar