Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Modernization
Samples

Simple AsyncAPI

This sample demonstrates how to generate an AsyncAPI schema document from NServiceBus endpoints using Neuroglia.AsyncApi.

Code walk-through

This sample contains four projects:

  • AsyncAPI.Feature - a class library containing shared code required to enable the custom AsyncApiFeature
  • Shared - a class library defining the events that are being published and subscribed to
  • AsyncAPI.GenericHost - a console application that publishes two events, and generates an AsyncAPI document schema for its structure and saves it to disk
  • Subscriber - a console application that subscribes to the events published by AsyncAPI.GenericHost

Feature project

The project contains all the necessary code for registering a custom AsyncAPI document schema generator.

The EndpointConfigurationExtensions enables the AsyncApiFeature.

public static void EnableAsyncApiSupport(
    this EndpointConfiguration endpointConfiguration)
{
    endpointConfiguration.EnableFeature<AsyncApiFeature>();
}

AsyncAPI feature

The feature creates a list of events and registers them in the container so that they are available to be used by the AsyncAPI document generator.

foreach (var messageMetadata in messageMetadataRegistry.GetAllMessages())
{
    if (conventions.IsEventType(messageMetadata.MessageType))
    {
        events.Add(messageMetadata.MessageType);
    }
}

context.Services.AddSingleton(new TypeCache
{
    EndpointName = context.Settings.EndpointName(),
    Events = events
});

Finally, the code registers a custom implementation of the Neuroglia IAsyncApiDocumentGenerator which will be used instead of the default implementation to generate the NServiceBus-specific schema document.

context.Services.AddTransient<IAsyncApiDocumentGenerator>(
    provider => new ApiDocumentGenerator(provider));
AsyncAPI document generator

This custom implementation of the Neuroglia IAsyncApiDocumentGenerator creates one AsyncAPI schema document for the NServiceBus endpoint hosted in the application. It demonstrates how channel information with the endpoint's address (queue name) can be generated, containing the publish operation and the payload of the event being published.

foreach (var publishedEvent in typeCache.Events)
{
    var channelName = $"{publishedEvent.FullName!}";
    document.WithChannel(channelName, channel =>
    {
        channelBuilder = channel;
        channel
            .WithAddress(typeCache.EndpointName)
            .WithDescription(publishedEvent.FullName);
    });
    await GenerateV3OperationForAsync(
        document,
        channelName,
        channelBuilder,
        publishedEvent,
        options,
        cancellationToken);
}

This code can be extended to include subscriptions, as well as sent/received messages.

Shared project

The project does not have any references to AsyncAPI. It contains two events that are published by the AsyncAPI.GenericHost application and subscribed to by the Subscriber endpoint.

Generic host project

Setup AsyncAPI

The project enables the AsyncAPI schema generation using three setup calls.

First, by adding the Neuroglia AsyncAPI.

builder.Services.AddAsyncApi();

Second, by adding the AsyncAPI feature to the NServiceBus endpoint.

endpointConfiguration.EnableAsyncApiSupport();

Lastly, by adding a background service to generate and write the AsyncAPI document schema to disk.

builder.Services.AddHostedService<AsyncAPISchemaWriter>();

Access AsyncAPI schema document

The AsyncAPISchemaWriter uses the custom document generator injected as part of the AsyncApiFeature to generate the document schema and write it to disk.

var documents = await apiDocumentGenerator.GenerateAsync(
    markupTypes: null!, options, cancellationToken);

var asyncApiDocuments = documents as IAsyncApiDocument[] ?? documents.ToArray();
if (!asyncApiDocuments.Any())
{
    logger.LogInformation("No documents generated.");
    return;
}

logger.LogInformation("Found #{Count} generated document(s).", asyncApiDocuments.Length);

foreach (var document in asyncApiDocuments)
{
    using MemoryStream stream = new();

    await asyncApiDocumentWriter.WriteAsync(
        document, stream, AsyncApiDocumentFormat.Json, cancellationToken);

    var schemaFile = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
        "downloads",
        $"{document.Title}.json");

    await File.WriteAllBytesAsync(schemaFile, stream.ToArray(), cancellationToken);

    logger.LogInformation($"Document {document.Title} written to {schemaFile}");
}

The file is saved into the default Downloads folder - it can be viewed using the AsyncAPI Studio (by pasting in the contents) and incorporated into internal system documentation.

Subscriber project

The project does not have any references to AsyncAPI. It contains handlers for events that it is subscribing to.

Running the sample

When running the solution with Visual Studio, two applications will start automatically.

AsyncAPI.GenericHost (console)

  • Press 1 to publish SampleEventOne - received by Subscriber.
  • Press 2 to publish SampleEventTwo - received by Subscriber.

Subscriber (console)

Displays all events published from AsyncAPI.GenericHost.

Samples