Kawa.FSharp 0.3.0

dotnet add package Kawa.FSharp --version 0.3.0
                    
NuGet\Install-Package Kawa.FSharp -Version 0.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Kawa.FSharp" Version="0.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Kawa.FSharp" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Kawa.FSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Kawa.FSharp --version 0.3.0
                    
#r "nuget: Kawa.FSharp, 0.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Kawa.FSharp@0.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Kawa.FSharp&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Kawa.FSharp&version=0.3.0
                    
Install as a Cake Tool

Design Principles

Kawa is a contract-first .NET web framework that lays a thin waterway on top of ASP.NET Core.

Kawa keeps application flow centered on request/response contracts and use cases. ASP.NET Core stays as the host and transport layer; Kawa only provides the small boundary pieces needed to execute use cases and translate KawaResult<T> values into HTTP responses.

Packages

  • Kawa.Abstractions: shared use case, result, and error contracts
  • Kawa.Core: transport-independent use case execution
  • Kawa.Web: ASP.NET Core Minimal API integration
  • Kawa.FSharp: F# helpers

Installation

dotnet add package Kawa.Web

Kawa.Web brings in the core Kawa runtime pieces needed for ASP.NET Core Minimal API integration.

Quick Start

Define one use case under UseCases/, with its request and response contracts nested in the same source file:

// UseCases/CreateUser.cs
using Kawa.Abstractions;

[KawaUseCase(
    "users.create",
    Summary = "Create user",
    Description = "Creates a user account.",
    Version = "v1",
    Tags = new[] { "Users" })]
[KawaErrorResponse(KawaErrorKind.Validation, Description = "Name is required.")]
public sealed class CreateUser
    : IUseCase<CreateUser.Request, CreateUser.Response>
{
    public sealed record Request(string Name);

    public sealed record Response(string Message);

    public Task<KawaResult<Response>> ExecuteAsync(
        Request request,
        CancellationToken cancellationToken = default)
    {
        if (string.IsNullOrWhiteSpace(request.Name))
        {
            var error = new KawaError(KawaErrorKind.Validation, "Name is required.");
            return Task.FromResult(KawaResult<Response>.Failure(error));
        }

        var response = new Response($"Created user {request.Name}.");
        return Task.FromResult(KawaResult<Response>.Success(response));
    }
}

Register Kawa, scan for use cases, and map the endpoint from the use case type:

using Kawa.Web;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddKawa()
    .AddKawaUseCasesFromAssemblies(typeof(CreateUser).Assembly)
    .AddKawaWeb();

var app = builder.Build();

app.MapKawaPost<CreateUser>("/users");
app.MapKawaApiCatalog();
app.MapKawaOpenApi();

if (app.Environment.IsDevelopment())
{
    app.MapKawaSwagger();
    app.MapKawaReDoc();
}

app.Run();

Kawa.Web exposes the same contracts through the Kawa API catalog at /kawa/catalog.json and OpenAPI at /openapi/v1.json. Swagger UI is available at /swagger and ReDoc is available at /redoc when the corresponding Kawa UI middleware is mapped. The convention is that Kawa request/response contracts are the source of the API catalog and OpenAPI schema.

The documentation UIs are middleware, so map them only where they should be public. The recommended default is development-only; exposing /swagger or /redoc in production should be an explicit application decision.

Use case metadata and error response attributes are transport-independent. Kawa.Web maps them to OpenAPI, and future RPC / CLI / Worker adapters can use the same API catalog.

Then call the endpoint:

curl -X POST http://localhost:5000/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Louisa"}'

Result to HTTP Mapping

MapKawaPost<TUseCase> reads the matching IUseCase<TRequest,TResponse> contract from the use case type, resolves that contract from dependency injection, executes it through UseCaseExecutor, and converts the result to an ASP.NET Core IResult.

MapKawaPost<TRequest,TResponse> is also available when you want to map explicit request and response types.

Current failure mappings:

KawaErrorKind HTTP response
Validation 400 Bad Request
Unauthorized 401 Unauthorized
Forbidden 403 Forbidden
NotFound 404 Not Found
Conflict 409 Conflict
Unknown 500 Problem

Samples

Run the C# sample:

dotnet run --project samples/Kawa.Sample.CSharp

Run the C# host + F# use case sample:

dotnet run --project samples/Kawa.Sample.FSharp

Run the mixed C# host + VB.NET use case sample:

dotnet run --project samples/Kawa.Sample.VB

All samples expose POST /users.

Development

Restore, build, and test:

dotnet restore Kawa.sln
dotnet build Kawa.sln --no-restore
dotnet test Kawa.sln --no-restore --no-build

Run tests with coverage:

dotnet test Kawa.sln \
  --no-restore \
  --no-build \
  --collect:"XPlat Code Coverage" \
  --results-directory TestResults \
  -- \
  DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=cobertura

The CI pipeline audits NuGet packages during restore and uploads coverage to Codecov using the repository secret CODECOV_TOKEN. Project and patch coverage are configured to target 100%.

Update both Changelog and 変更履歴 日本語版 whenever a change is added. During development, record changes under the current Unreleased version section. Before releasing, replace Unreleased with the release date for that version.

To create local NuGet packages:

bash eng/pack.sh

To publish the generated packages to NuGet.org:

NUGET_API_KEY=... bash eng/push-nuget.sh

NuGet packages and GitHub Releases are published by GitHub Actions when a tag in vX.Y.Z format is pushed, for example:

git tag v0.1.1
git push origin v0.1.1

The release workflow uses the repository secret NUGET_API_KEY. GitHub Release notes are generated from the matching version section in the English and Japanese changelogs.

See:

License

Kawa is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.0 53 5/27/2026
0.2.1 67 5/26/2026
0.2.0 77 5/26/2026
0.1.1 88 5/24/2026
0.1.0 88 5/22/2026