Bielu.AspNetCore.AsyncApi.Attributes
1.0.0-beta.639091575668923887
Prefix Reserved
dotnet add package Bielu.AspNetCore.AsyncApi.Attributes --version 1.0.0-beta.639091575668923887
NuGet\Install-Package Bielu.AspNetCore.AsyncApi.Attributes -Version 1.0.0-beta.639091575668923887
<PackageReference Include="Bielu.AspNetCore.AsyncApi.Attributes" Version="1.0.0-beta.639091575668923887" />
<PackageVersion Include="Bielu.AspNetCore.AsyncApi.Attributes" Version="1.0.0-beta.639091575668923887" />
<PackageReference Include="Bielu.AspNetCore.AsyncApi.Attributes" />
paket add Bielu.AspNetCore.AsyncApi.Attributes --version 1.0.0-beta.639091575668923887
#r "nuget: Bielu.AspNetCore.AsyncApi.Attributes, 1.0.0-beta.639091575668923887"
#:package Bielu.AspNetCore.AsyncApi.Attributes@1.0.0-beta.639091575668923887
#addin nuget:?package=Bielu.AspNetCore.AsyncApi.Attributes&version=1.0.0-beta.639091575668923887&prerelease
#tool nuget:?package=Bielu.AspNetCore.AsyncApi.Attributes&version=1.0.0-beta.639091575668923887&prerelease
Bielu.AspNetCore.AsyncApi
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:
- Saunter - The original AsyncAPI documentation generator for .NET
- Microsoft.AspNetCore.OpenApi - Microsoft's OpenAPI implementation that inspired the API design
- ByteBard.AsyncAPI.NET - AsyncAPI schema and serialization
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."
}
}
}
}
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:
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 });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.
Option 1: Using Microsoft.Extensions.ApiDescription.Server (Recommended)
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.Serverpackage depends on thedotnet asyncapiCLI 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.jsonGET /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
AsyncApiprefix (e.g.,Info→AsyncApiInfo) - All data structure constructors are now parameterless
- The service registration method has changed from
AddAsyncApiSchemaGenerationtoAddAsyncApi
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 | Versions 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. |
-
net10.0
- ByteBard.AsyncAPI.NET (>= 2.1.3-beta.14)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Bielu.AspNetCore.AsyncApi.Attributes:
| Package | Downloads |
|---|---|
|
Bielu.AspNetCore.AsyncApi
Package Description |
|
|
Bielu.AspNetCore.AsyncApi.UI
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-beta.639091575668923887 | 27 | 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 | 32 | 3/12/2026 |
| 1.0.0-beta.639088111535456095 | 35 | 3/11/2026 |
| 1.0.0-beta.639088109296804148 | 39 | 3/11/2026 |
| 1.0.0-beta.639086741539077587 | 40 | 3/9/2026 |
| 1.0.0-beta.639076433361017050 | 45 | 2/25/2026 |
| 1.0.0-beta.639068353194068762 | 55 | 2/16/2026 |
| 1.0.0-beta.639057127979931780 | 57 | 2/3/2026 |
| 1.0.0-beta.639056414730379938 | 49 | 2/2/2026 |
| 1.0.0-beta.639056389507307908 | 52 | 2/2/2026 |