Bielu.AspNetCore.AsyncApi.Merger 1.0.0-beta.639091575668923887

Prefix Reserved
This is a prerelease version of Bielu.AspNetCore.AsyncApi.Merger.
dotnet add package Bielu.AspNetCore.AsyncApi.Merger --version 1.0.0-beta.639091575668923887
                    
NuGet\Install-Package Bielu.AspNetCore.AsyncApi.Merger -Version 1.0.0-beta.639091575668923887
                    
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="Bielu.AspNetCore.AsyncApi.Merger" Version="1.0.0-beta.639091575668923887" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Bielu.AspNetCore.AsyncApi.Merger" Version="1.0.0-beta.639091575668923887" />
                    
Directory.Packages.props
<PackageReference Include="Bielu.AspNetCore.AsyncApi.Merger" />
                    
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 Bielu.AspNetCore.AsyncApi.Merger --version 1.0.0-beta.639091575668923887
                    
#r "nuget: Bielu.AspNetCore.AsyncApi.Merger, 1.0.0-beta.639091575668923887"
                    
#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 Bielu.AspNetCore.AsyncApi.Merger@1.0.0-beta.639091575668923887
                    
#: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=Bielu.AspNetCore.AsyncApi.Merger&version=1.0.0-beta.639091575668923887&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Bielu.AspNetCore.AsyncApi.Merger&version=1.0.0-beta.639091575668923887&prerelease
                    
Install as a Cake Tool

Bielu.AspNetCore.AsyncApi

CI NuGet NuGet Downloads License: MIT

Bielu.AspNetCore.AsyncApi provides built-in support for generating AsyncAPI documents from minimal or controller-based APIs in ASP.NET Core. This library brings the same developer experience as Microsoft.AspNetCore.OpenApi but for AsyncAPI specifications.

⚠️ Note: Pre version 1.0.0, the API is regarded as unstable and breaking changes may be introduced.

About

This project is based on and inspired by:

Key Features

  • Runtime document generation - View generated AsyncAPI documents at runtime via a parameterized endpoint (/asyncapi/{documentName}.json)
  • Build-time document generation - Generate AsyncAPI documents at build-time for static hosting
  • Document transformers - Customize the generated document via document transformers
  • Schema transformers - Customize the generated schema via schema transformers
  • Protocol bindings - Support for AMQP, HTTP, MQTT, Kafka, and other protocol bindings
  • Multiple documents - Generate multiple AsyncAPI documents from a single application
  • Interactive UI - Built-in AsyncAPI UI for exploring your API documentation
  • Attribute-based configuration - Decorate your classes with attributes to define channels and operations

Installation

Install the packages from NuGet:

# Core package for AsyncAPI document generation
dotnet add package Bielu.AspNetCore.AsyncApi

# Optional: Attributes package for annotating your classes
dotnet add package Bielu.AspNetCore.AsyncApi.Attributes

# Optional: UI package for interactive documentation
dotnet add package Bielu.AspNetCore.AsyncApi.UI

Examples

Example Description
StreetlightsAPI Minimal single-service example — MQTT-based streetlight monitoring with subscribe/publish operations. Great starting point for learning the attribute-based API.
Aspire Mini Shop Distributed microservices demo built with .NET Aspire — Order Service, Inventory Service, Notification Service, and a YARP API Gateway that merges AsyncAPI docs from all downstream services. Uses Kafka, PostgreSQL, Valkey, SignalR, Scrutor decorator pattern, and OpenTelemetry.

Getting Started

See the StreetlightsAPI example for a complete working example.

1. Configure Services

In your Program.cs or Startup.cs, configure AsyncAPI services:

using Bielu.AspNetCore.AsyncApi.Extensions;
using Bielu.AspNetCore.AsyncApi.UI;

var builder = WebApplication.CreateBuilder(args);

// Add AsyncAPI services
builder.Services.AddAsyncApi(options =>
{
    options.AddServer("mosquitto", "test.mosquitto.org", "mqtt", server =>
    {
        server.Description = "Test Mosquitto MQTT Broker";
    });
    options.AddServer("webapi", "localhost:5000", "http", server =>
    {
        server.Description = "Local HTTP API Server";
    });
    options.WithDefaultContentType("application/json")
        .WithDescription("The Smartylighting Streetlights API allows you to remotely manage the city lights.")
        .WithLicense("Apache 2.0", "https://www.apache.org/licenses/LICENSE-2.0");
});

var app = builder.Build();

// Map the AsyncAPI document endpoint
app.MapAsyncApi();

// Optional: Map the AsyncAPI UI
app.MapAsyncApiUi();

app.Run();

2. Define Channels with Attributes

Decorate your message bus classes with attributes:

using Bielu.AspNetCore.AsyncApi.Attributes.Attributes;

[AsyncApi] // Tells the library to scan this class
public class StreetlightMessageBus : IStreetlightMessageBus
{
    private const string LightMeasuredTopic = "subscribe/light/measured";

    [Channel(LightMeasuredTopic, Servers = new[] { "mosquitto" })]
    [SubscribeOperation(typeof(LightMeasuredEvent), "Light", 
        Summary = "Subscribe to environmental lighting conditions for a particular streetlight.")]
    public void PublishLightMeasurement(LightMeasuredEvent lightMeasuredEvent)
    {
        // Publish message to the channel
    }
}

3. Access the Generated Document

Once configured, access your AsyncAPI document:

  • JSON Document: GET /asyncapi/v1.json
  • AsyncAPI UI: GET /asyncapi
{
  "asyncapi": "2.6.0",
  "info": {
    "title": "Streetlights API",
    "version": "1.0.0",
    "description": "The Smartylighting Streetlights API allows you to remotely manage the city lights."
  },
  "channels": {
    "subscribe/light/measured": {
      "subscribe": {
        "operationId": "PublishLightMeasurement",
        "summary": "Subscribe to environmental lighting conditions for a particular streetlight."
      }
    }
  }
}

AsyncAPI UI

Main Types

The main types provided by this library are:

Type Description
AsyncApiOptions Options for configuring AsyncAPI document generation
IAsyncApiDocumentTransformer Interface for transformers that modify the generated AsyncAPI document
IAsyncApiSchemaTransformer Interface for transformers that modify generated schemas
AsyncApiAttribute Marks a class for scanning by the AsyncAPI generator
ChannelAttribute Defines a channel on a method
SubscribeOperationAttribute Defines a subscribe operation on a channel
PublishOperationAttribute Defines a publish operation on a channel
MessageAttribute Defines message metadata

Configuration Options

Configure the library with the fluent API:

builder.Services.AddAsyncApi(options =>
{
    // Add servers
    options.AddServer("production", "api.example.com", "amqp");
    
    // Add protocol bindings
    options.AddChannelBinding("amqpDev", new AMQPChannelBinding
    {
        Is = ChannelType.Queue,
        Queue = new Queue { Name = "example-queue", Vhost = "/development" }
    });
    
    options.AddOperationBinding("postBind", new HttpOperationBinding
    {
        Method = "POST",
        Type = HttpOperationType.Response
    });
    
    // Configure document metadata
    options.WithDefaultContentType("application/json")
        .WithDescription("My API Description")
        .WithLicense("MIT", "https://opensource.org/licenses/MIT");
    
    // Add transformers
    options.AddDocumentTransformer<MyCustomTransformer>();
    options.AddSchemaTransformer<MySchemaTransformer>();
});

Version-Specific Requirements

AsyncAPI 2.x

When using AsyncAPI 2.x specification (AsyncApiVersion.AsyncApi2_0), at least one channel must be defined. The AsyncAPI 2.x specification requires the channels field to be present and non-empty.

If your application doesn't define any channels (e.g., for documentation purposes only), you have two options:

  1. Use AsyncAPI 3.x (recommended) - AsyncAPI 3.x does not require channels:

    builder.Services.AddAsyncApi(options =>
    {
        options.AsyncApiVersion = AsyncApiVersion.AsyncApi3_0; // Default
        options.WithInfo("My API", "1.0.0");
        // No channels required
    });
    
  2. Define at least one channel for AsyncAPI 2.x:

    builder.Services.AddAsyncApi(options =>
    {
        options.AsyncApiVersion = AsyncApiVersion.AsyncApi2_0;
        options.WithInfo("My API", "1.0.0");
        // Must have at least one channel defined via attributes
    });
    

⚠️ Note: Documents generated with AsyncAPI 2.x without any channels will fail validation. This is a requirement of the AsyncAPI 2.x specification, not a limitation of this library.

AsyncAPI 3.x

AsyncAPI 3.x (default) does not require channels. This version is recommended for most new projects as it provides more flexibility and supports the latest AsyncAPI features including AsyncAPI 3.1 schema generation.

Build-Time Document Generation

You can generate AsyncAPI documents at build time, which is useful for CI pipelines, source control tracking, and distributing API specs without launching the app.

The Bielu.AspNetCore.AsyncApi library is compatible with Microsoft.Extensions.ApiDescription.Server, which uses the built-in dotnet getdocument tool:

dotnet add package Microsoft.Extensions.ApiDescription.Server

Then configure your .csproj:

<PropertyGroup>
    <OpenApiGenerateDocuments>true</OpenApiGenerateDocuments>
    <OpenApiDocumentsDirectory>$(MSBuildProjectDirectory)</OpenApiDocumentsDirectory>
    <OpenApiGenerateDocumentsOnBuild>true</OpenApiGenerateDocumentsOnBuild>
</PropertyGroup>

AsyncAPI documents will be generated during dotnet build using the IDocumentProvider interface registered by AddAsyncApi().

Option 2: Using the AsyncAPI CLI Tool

Install the dotnet asyncapi CLI tool for more control:

dotnet tool install -g Bielu.AspNetCore.AsyncApi.Cli

Generate documents from a built project:

dotnet asyncapi getdocument \
    --assembly MyApp \
    --assembly-path bin/Debug/net10.0/MyApp.dll \
    --output ./docs \
    --project MyApp

CLI options:

  • --assembly <name> - Assembly name to load (required)
  • --output <dir> - Output directory for generated documents (required)
  • --project <name> - Project name for file naming
  • --document <name> - Generate only the specified document
  • --file-name <name> - Override file name (without extension)

Option 3: Using MSBuild Targets

Add the MSBuild targets package for automatic build-time generation. This package provides MSBuild .props and .targets files that invoke the dotnet asyncapi CLI tool (Option 2) after each build:

dotnet add package Bielu.AspNetCore.AsyncApi.ApiDescription.Server
dotnet tool install -g Bielu.AspNetCore.AsyncApi.Cli

Note: The Bielu.AspNetCore.AsyncApi.ApiDescription.Server package depends on the dotnet asyncapi CLI tool being installed. Install the CLI tool globally or as a local tool before building.

Configure your .csproj:

<PropertyGroup>
    <AsyncApiGenerateDocumentsOnBuild>true</AsyncApiGenerateDocumentsOnBuild>
    <AsyncApiDocumentsDirectory>$(MSBuildProjectDirectory)/docs</AsyncApiDocumentsDirectory>
</PropertyGroup>

Available MSBuild properties: | Property | Default | Description | |----------|---------|-------------| | AsyncApiGenerateDocumentsOnBuild | true | Enable/disable document generation on build | | AsyncApiDocumentsDirectory | $(OutputPath) | Output directory for generated documents | | AsyncApiDocumentName | (empty) | Generate only the specified document | | AsyncApiFileName | (empty) | Override output file name |

Protocol Bindings

Bindings describe protocol-specific information. Apply them to channels and operations using the BindingsRef property:

// Configure bindings
builder.Services.AddAsyncApi(options =>
{
    options.AddChannelBinding("amqpDev", new AMQPChannelBinding
    {
        Is = ChannelType.Queue,
        Queue = new Queue { Name = "example-queue", Vhost = "/development" }
    });
});

// Use bindings in attributes
[Channel("light.measured", BindingsRef = "amqpDev")]
[SubscribeOperation(typeof(LightMeasuredEvent), "Light")]
public void PublishLightMeasuredEvent(LightMeasuredEvent lightMeasuredEvent) { }

Available bindings: AsyncAPI.NET.Bindings

Multiple AsyncAPI Documents

Generate multiple AsyncAPI documents by specifying document names:

// Configure named documents
builder.Services.AddAsyncApi("internal", options =>
{
    options.WithDescription("Internal API");
});

builder.Services.AddAsyncApi("public", options =>
{
    options.WithDescription("Public API");
});

Decorate classes with the document name:

[AsyncApi("internal")]
public class InternalMessageBus { }

[AsyncApi("public")]
public class PublicMessageBus { }

Access documents by name:

  • GET /asyncapi/internal/asyncapi.json
  • GET /asyncapi/public/asyncapi.json

Migration from Saunter

If you're migrating from the original Saunter library, note these changes:

Namespace Changes

Old New
Saunter.AsyncApiSchema.v2 ByteBard.AsyncAPI.Models
Saunter.Attributes Bielu.AspNetCore.AsyncApi.Attributes.Attributes

API Changes

  • Data structure names now have an AsyncApi prefix (e.g., InfoAsyncApiInfo)
  • All data structure constructors are now parameterless
  • The service registration method has changed from AddAsyncApiSchemaGeneration to AddAsyncApi

Example Migration

Before (Saunter):

services.AddAsyncApiSchemaGeneration(options =>
{
    options.AssemblyMarkerTypes = new[] { typeof(MyMessageBus) };
    options.AsyncApi = new AsyncApiDocument { ... };
});

app.UseEndpoints(endpoints =>
{
    endpoints.MapAsyncApiDocuments();
    endpoints.MapAsyncApiUi();
});

After (Bielu.AspNetCore.AsyncApi):

builder.Services.AddAsyncApi(options =>
{
    options.AddServer("mosquitto", "test.mosquitto.org", "mqtt");
    options.WithDescription("My API");
});

app.MapAsyncApi();
app.MapAsyncApiUi();

Contributing

We welcome contributions! See our Contributing Guide for details on:

  • Setting up your development environment
  • Building and testing the project
  • Submitting pull requests

Feel free to get involved by opening issues or submitting pull requests.

Acknowledgments

This project builds upon the excellent work of:

  • Saunter - The original AsyncAPI documentation generator for .NET, maintained by the AsyncAPI Initiative
  • Microsoft.AspNetCore.OpenApi - Microsoft's OpenAPI implementation that inspired the fluent API design
  • ByteBard.AsyncAPI.NET - AsyncAPI schema models and serialization (fork of LEGO AsyncAPI.NET)
  • Swashbuckle - The OpenAPI/Swagger implementation that inspired the original Saunter project

License

This project is licensed under the MIT License - see the LICENSE file for details.

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
1.0.0-beta.639091575668923887 19 3/15/2026
1.0.0-beta.639091048070992726 27 3/14/2026
1.0.0-beta.639090979247460713 28 3/14/2026
1.0.0-beta.639088982709010252 35 3/12/2026