Skip to content

Commit 703ac5a

Browse files
committed
docs: add documentation structure and build process
This commit adds the documentation structure across various files, introduces new documentation bindings, and updates the Docusaurus configuration. The core changes involve: Updating the Docusaurus configuration (`website/docusaurus.config.js`) and sidebars (`website/sidebars.js`) to reflect the new structure. Adding new documentation files for various protocol bindings (AMQP, Google Pub/Sub, HTTP, IBM MQ, JMS, Kafka, NATS, Pulsar, ROS 2, SNS, Solace, SQS, WebSockets) within `website/docs/bindings/`. Expanding the guides section with new documentation on Avro, custom bindings, schema parsers, and validation rules in `website/docs/guides/`. Updating the main README to reflect the version change to `asyncapi: 3.1.0`. Modifying the main page component (`website/src/pages/index.js`) to correctly map library usage, extensions, and bindings in the navigation structure. Adding custom CSS variables and styling to `website/src/css/custom.css`. Adding a GitHub Actions workflow file (`.github/workflows/docs
1 parent c0c5ab2 commit 703ac5a

46 files changed

Lines changed: 21799 additions & 3 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/docs.yml‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Build and deploy documentation
2+
3+
on:
4+
pull_request:
5+
branches: [vnext]
6+
paths:
7+
- 'website/**'
8+
- '.github/workflows/docs.yml'
9+
push:
10+
branches: [vnext]
11+
paths:
12+
- 'website/**'
13+
- '.github/workflows/docs.yml'
14+
15+
permissions:
16+
contents: read
17+
18+
concurrency:
19+
group: pages
20+
cancel-in-progress: false
21+
22+
jobs:
23+
build:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Check out repository
27+
uses: actions/checkout@v4
28+
- name: Set up Node.js
29+
uses: actions/setup-node@v4
30+
with:
31+
node-version: 24
32+
cache: npm
33+
cache-dependency-path: website/package-lock.json
34+
- name: Install dependencies
35+
working-directory: website
36+
run: npm ci
37+
- name: Build website
38+
working-directory: website
39+
run: npm run build
40+
- name: Upload Pages artifact
41+
uses: actions/upload-pages-artifact@v3
42+
with:
43+
path: website/build
44+
45+
deploy:
46+
if: github.event_name == 'push' && github.ref == 'refs/heads/vnext'
47+
needs: build
48+
runs-on: ubuntu-latest
49+
permissions:
50+
pages: write
51+
id-token: write
52+
environment:
53+
name: github-pages
54+
url: ${{ steps.deployment.outputs.page_url }}
55+
steps:
56+
- name: Deploy to GitHub Pages
57+
id: deployment
58+
uses: actions/deploy-pages@v4

‎README.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ This is unfortunate, but after much back and not a lot of forth, I have decided
77

88

99
The AsyncAPI.NET SDK contains a useful object model for the AsyncAPI specification in .NET along with common serializers to extract raw AsyncAPI JSON and YAML documents from the model as well.
10-
Full support for both 2.6 and 3.0.
11-
2.6 are 'upgraded' to 3.0 during deserialization and can be written back as 2.6 (see writing examples).
10+
AsyncAPI.NET supports the current releases of the AsyncAPI 2.x and 3.x major versions. Today, serialization emits 2.6 or 3.1.0 respectively.
11+
V2 documents are upgraded to the V3 model during deserialization and can be written back as V2 (see writing examples). The V3 serialization selector is still named `AsyncApiVersion.AsyncApi3_0`.
1212

1313
[CHANGELOG](https://github.com/ByteBardOrg/AsyncAPI.NET/blob/vnext/CHANGELOG.md)
1414
[Wiki and getting started guide](https://github.com/ByteBardOrg/AsyncAPI.NET/wiki)
1515

16+
## Documentation
17+
The [documentation site](https://bytebardorg.github.io/AsyncAPI.NET/) is built with Docusaurus. See [website/README.md](website/README.md) for local development instructions. GitHub Pages must be configured to use GitHub Actions for deployment.
18+
1619
## Installation
1720
Generally you want to use Readers and Bindings.
1821
They have however been split to allow for different scenarios without polluting with unnecesary packages.
@@ -42,7 +45,7 @@ Main classes to know:
4245
```csharp
4346
var specification =
4447
"""
45-
asyncapi: 3.0.0
48+
asyncapi: 3.1.0
4649
info:
4750
title: UsersAPI
4851
version: 1.0.0

‎website/.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/.docusaurus/
2+
/build/
3+
/node_modules/

‎website/README.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# AsyncAPI.NET documentation site
2+
3+
The documentation site is built with Docusaurus 3. From this directory:
4+
5+
```sh
6+
npm install
7+
npm start
8+
```
9+
10+
Open the local address printed by Docusaurus (normally http://localhost:3000/AsyncAPI.NET/). To create and preview the production site, run `npm run build` and then `npm run serve`.
11+
12+
The deployed site is configured for GitHub Pages at https://bytebardorg.github.io/AsyncAPI.NET/.
13+
14+
Documentation lives in two directories:
15+
16+
- `docs/guides/` contains the **Use the library** guides (getting started, reading, references, schemas, and version conversion) and the **Extend the library** guides (extensions, custom bindings, custom schema parsers, and validation rules). Both sections share a sidebar, arranged in `sidebars.js`.
17+
- `docs/bindings/` contains protocol-specific binding pages. Its sidebar is generated automatically from the files in that directory.
18+
19+
Add a guide or binding page to its matching directory. Update `sidebars.js` when adding guides so it appears in the appropriate section.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"label": "Protocol bindings",
3+
"position": 5,
4+
"link": {
5+
"type": "doc",
6+
"id": "bindings/index"
7+
}
8+
}

‎website/docs/bindings/amqp.md‎

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
sidebar_position: 2
3+
title: AMQP bindings
4+
description: Read and write AMQP channel, operation, and message bindings.
5+
---
6+
7+
# AMQP
8+
9+
AMQP parsers are registered by `BindingsCollection.AMQP` (also included by `All`). Supported levels are channel (`AMQPChannelBinding`), operation (`AMQPOperationBinding`), and message (`AMQPMessageBinding`).
10+
11+
## Write
12+
13+
```csharp
14+
using System.Collections.Generic;
15+
using ByteBard.AsyncAPI.Bindings.AMQP;
16+
using ByteBard.AsyncAPI.Models;
17+
18+
var channel = new AsyncApiChannel();
19+
channel.Bindings.Add(new AMQPChannelBinding
20+
{
21+
Is = ChannelType.RoutingKey,
22+
Exchange = new Exchange
23+
{
24+
Name = "orders",
25+
Type = ExchangeType.Topic,
26+
Durable = true,
27+
Vhost = "/",
28+
},
29+
});
30+
31+
var operation = new AsyncApiOperation();
32+
operation.Bindings.Add(new AMQPOperationBinding
33+
{
34+
Expiration = 60_000,
35+
UserId = "publisher",
36+
Cc = new List<string> { "orders.created" },
37+
Priority = 5,
38+
DeliveryMode = DeliveryMode.Persistent,
39+
Mandatory = true,
40+
Ack = true,
41+
});
42+
```
43+
44+
Set `Is` to `ChannelType.Queue` and provide `Queue` for a queue channel; set it to `ChannelType.RoutingKey` and provide `Exchange` for an exchange channel. Serialization writes only the matching `Queue` or `Exchange` object.
45+
46+
## Read and use
47+
48+
Register the AMQP parsers, parse a channel fragment, then retrieve the typed binding with `TryGetValue<TBinding>`:
49+
50+
```csharp
51+
using ByteBard.AsyncAPI;
52+
using ByteBard.AsyncAPI.Bindings;
53+
using ByteBard.AsyncAPI.Bindings.AMQP;
54+
using ByteBard.AsyncAPI.Models;
55+
using ByteBard.AsyncAPI.Readers;
56+
57+
var settings = new AsyncApiReaderSettings { Bindings = BindingsCollection.AMQP };
58+
var parsed = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>("""
59+
bindings:
60+
amqp:
61+
is: queue
62+
queue:
63+
name: orders
64+
""", AsyncApiVersion.AsyncApi3_0, out var diagnostics);
65+
66+
if (parsed.Bindings.TryGetValue<AMQPChannelBinding>(out var amqp))
67+
{
68+
Console.WriteLine(amqp.Is == ChannelType.Queue
69+
? amqp.Queue.Name
70+
: amqp.Exchange.Name);
71+
}
72+
73+
var parsedOperation = new AsyncApiStringReader(settings).ReadFragment<AsyncApiOperation>("""
74+
bindings:
75+
amqp:
76+
expiration: 60000
77+
priority: 5
78+
deliveryMode: 2
79+
mandatory: true
80+
ack: true
81+
""", AsyncApiVersion.AsyncApi3_0, out diagnostics);
82+
if (parsedOperation.Bindings.TryGetValue<AMQPOperationBinding>(out var amqpOperation))
83+
{
84+
Console.WriteLine(amqpOperation.Expiration);
85+
}
86+
```
87+
88+
Channel fields: `Is` (`ChannelType`), `Exchange` (`Exchange`), and `Queue` (`Queue`). `Exchange` carries `Name`, `Type`, `Durable`, `AutoDelete`, and `Vhost`; `Queue` carries `Name`, `Durable`, `Exclusive`, `AutoDelete`, and `Vhost`. Both `Vhost` values default to `/`. The enum choices are defined by `ChannelType` and `ExchangeType`.
89+
90+
Operation fields include `Expiration` (`uint`), `UserId`, `Cc`/`Bcc` lists, `Priority`, `DeliveryMode`, `Mandatory`, `Timestamp`, and `Ack`. Message fields are `ContentEncoding` and `MessageType`.
91+
92+
At the other supported levels, attach `AMQPOperationBinding` to an operation and `AMQPMessageBinding` to a message. Numeric fields and flags are represented by CLR numeric/boolean types; the model does not enforce broker-side limits or semantic combinations.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
sidebar_position: 3
3+
title: Anypoint MQ bindings
4+
description: Read and write Anypoint MQ channel and message bindings.
5+
---
6+
7+
# Anypoint MQ
8+
9+
`BindingsCollection.AnypointMQ` registers channel and message parsers (and is included in `All`). There is no Anypoint MQ server or operation binding parser in this collection.
10+
11+
## Write
12+
13+
Attach typed channel and message binding instances with `Bindings.Add`; the binding key is supplied by each binding type:
14+
15+
```csharp
16+
using ByteBard.AsyncAPI.Bindings.AnypointMQ;
17+
using ByteBard.AsyncAPI.Models;
18+
19+
var channel = new AsyncApiChannel();
20+
channel.Bindings.Add(new AnypointMQChannelBinding
21+
{
22+
Destination = "orders",
23+
DestinationType = "exchange",
24+
});
25+
26+
var message = new AsyncApiMessage();
27+
message.Bindings.Add(new AnypointMQMessageBinding
28+
{
29+
Headers = new AsyncApiJsonSchema
30+
{
31+
Type = SchemaType.Object,
32+
Properties =
33+
{
34+
["traceId"] = new AsyncApiJsonSchema { Type = SchemaType.String },
35+
},
36+
},
37+
});
38+
```
39+
40+
## Read and use
41+
42+
Register the Anypoint MQ parsers, parse a channel fragment, and use its typed destination field:
43+
44+
```csharp
45+
using ByteBard.AsyncAPI;
46+
using ByteBard.AsyncAPI.Bindings;
47+
using ByteBard.AsyncAPI.Bindings.AnypointMQ;
48+
using ByteBard.AsyncAPI.Models;
49+
using ByteBard.AsyncAPI.Readers;
50+
51+
var settings = new AsyncApiReaderSettings { Bindings = BindingsCollection.AnypointMQ };
52+
var parsed = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>("""
53+
bindings:
54+
anypointmq:
55+
destination: orders
56+
destinationType: queue
57+
""", AsyncApiVersion.AsyncApi3_0, out var diagnostics);
58+
59+
if (parsed.Bindings.TryGetValue<AnypointMQChannelBinding>(out var anypoint))
60+
{
61+
Console.WriteLine(anypoint.Destination);
62+
}
63+
64+
var parsedMessage = new AsyncApiStringReader(settings).ReadFragment<AsyncApiMessage>("""
65+
bindings:
66+
anypointmq:
67+
headers:
68+
type: object
69+
properties:
70+
traceId:
71+
type: string
72+
""", AsyncApiVersion.AsyncApi3_0, out diagnostics);
73+
if (parsedMessage.Bindings.TryGetValue<AnypointMQMessageBinding>(out var anypointMessage))
74+
{
75+
Console.WriteLine(anypointMessage.Headers.Properties["traceId"].Type);
76+
}
77+
```
78+
79+
Channel fields are `Destination` and `DestinationType` (strings). Message-level metadata is `Headers` (`AsyncApiJsonSchema`); attach it with `message.Bindings.Add(new AnypointMQMessageBinding { Headers = headers });`.
80+
81+
`Headers` accepts an inline schema or a schema reference, for example `new AsyncApiJsonSchemaReference("#/components/schemas/messageHeaders")`; after reading, inspect the resulting `Headers` schema or reference on the typed message binding.
82+
83+
The same registration includes message bindings; attach `AnypointMQMessageBinding` to a message when writing. Schemas are represented as `AsyncApiJsonSchema`; this package models metadata and does not contact Anypoint MQ or validate destination names.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
sidebar_position: 4
3+
title: Google Pub/Sub bindings
4+
description: Read and write Google Pub/Sub channel and message bindings.
5+
---
6+
7+
# Google Pub/Sub
8+
9+
`BindingsCollection.GooglePubSub` registers channel and message levels; it is also part of `All`.
10+
11+
## Write
12+
13+
Attach channel-level settings to an `AsyncApiChannel`:
14+
15+
```csharp
16+
using System.Collections.Generic;
17+
using ByteBard.AsyncAPI.Bindings.GooglePubSub;
18+
using ByteBard.AsyncAPI.Models;
19+
20+
var channel = new AsyncApiChannel();
21+
channel.Bindings.Add(new GooglePubSubChannelBinding
22+
{
23+
Labels = new Dictionary<string, string> { ["team"] = "fulfillment" },
24+
MessageRetentionDuration = "86400s",
25+
MessageStoragePolicy = new MessageStoragePolicy
26+
{
27+
AllowedPersistenceRegions = new[] { "us-central1", "us-east1" },
28+
},
29+
SchemaSettings = new SchemaSettings
30+
{
31+
Encoding = "JSON",
32+
FirstRevisionId = "1",
33+
LastRevisionId = "3",
34+
Name = "projects/example/schemas/orders",
35+
},
36+
});
37+
38+
var message = new AsyncApiMessage();
39+
message.Bindings.Add(new GooglePubSubMessageBinding
40+
{
41+
Attributes = new Dictionary<string, string> { ["source"] = "billing" },
42+
OrderingKey = "customer-7",
43+
Schema = new MessageSchema { Name = "projects/example/schemas/orders" },
44+
});
45+
```
46+
47+
## Read and use
48+
49+
Register the channel and message parsers, parse a channel fragment, and access a typed field from the channel's `Bindings` dictionary:
50+
51+
```csharp
52+
using ByteBard.AsyncAPI;
53+
using ByteBard.AsyncAPI.Bindings;
54+
using ByteBard.AsyncAPI.Bindings.GooglePubSub;
55+
using ByteBard.AsyncAPI.Models;
56+
using ByteBard.AsyncAPI.Readers;
57+
58+
var settings = new AsyncApiReaderSettings { Bindings = BindingsCollection.GooglePubSub };
59+
var parsed = new AsyncApiStringReader(settings).ReadFragment<AsyncApiChannel>("""
60+
bindings:
61+
googlepubsub:
62+
labels:
63+
team: fulfillment
64+
messageRetentionDuration: 86400s
65+
messageStoragePolicy:
66+
allowedPersistenceRegions:
67+
- us-central1
68+
- us-east1
69+
schemaSettings:
70+
encoding: JSON
71+
firstRevisionId: '1'
72+
lastRevisionId: '3'
73+
name: projects/example/schemas/orders
74+
""", AsyncApiVersion.AsyncApi3_0, out var diagnostics);
75+
76+
if (parsed.Bindings.TryGetValue<GooglePubSubChannelBinding>(out var pubSub))
77+
{
78+
Console.WriteLine(pubSub.Labels["team"]);
79+
foreach (var region in pubSub.MessageStoragePolicy.AllowedPersistenceRegions)
80+
{
81+
Console.WriteLine(region);
82+
}
83+
Console.WriteLine(pubSub.SchemaSettings.Name);
84+
}
85+
86+
var parsedMessage = new AsyncApiStringReader(settings).ReadFragment<AsyncApiMessage>("""
87+
bindings:
88+
googlepubsub:
89+
schema:
90+
name: projects/example/schemas/orders
91+
orderingKey: customer-7
92+
""", AsyncApiVersion.AsyncApi3_0, out diagnostics);
93+
if (parsedMessage.Bindings.TryGetValue<GooglePubSubMessageBinding>(out var pubSubMessage))
94+
{
95+
Console.WriteLine(pubSubMessage.Schema.Name);
96+
}
97+
```
98+
99+
Channel fields: `Labels` (`Dictionary<string,string>`), `MessageRetentionDuration` (`string`), `MessageStoragePolicy` (`AllowedPersistenceRegions`, a sequence of strings), and `SchemaSettings` (`Encoding`, `FirstRevisionId`, `LastRevisionId`, and `Name`, all strings). Message fields: `Attributes` (`Dictionary<string,string>`), `OrderingKey`, and `Schema` (`MessageSchema`, whose `Name` is a string). This message `Schema` is Pub/Sub schema metadata, not an `AsyncApiJsonSchema` payload schema.
100+
101+
For message-level writes, attach a `GooglePubSubMessageBinding` with `message.Bindings.Add(new GooglePubSubMessageBinding { ... });`; it provides `Attributes`, `OrderingKey`, and `Schema`. Duration text and nested schema/storage settings are retained as model data; the library does not verify them against a live topic.

0 commit comments

Comments
 (0)