Skip to content

Commit cac8da4

Browse files
committed
Update docs
1 parent a6ac920 commit cac8da4

2 files changed

Lines changed: 28 additions & 66 deletions

File tree

docs/api/appending-events.md

Lines changed: 11 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -146,38 +146,6 @@ This feature is only available in KurrentDB 25.1 and later.
146146

147147
You can append events to multiple streams in a single atomic operation. Either all streams are updated, or the entire operation fails.
148148

149-
The `MultiStreamAppendAsync` method accepts a collection of `AppendStreamRequest` objects and returns a `MultiAppendWriteResult`. Each `AppendStreamRequest` contains:
150-
151-
- **Stream** - The name of the stream
152-
- **ExpectedState** - The expected state of the stream for optimistic concurrency control
153-
- **Messages** - A collection of `EventData` objects to append
154-
155-
The operation returns either:
156-
- `MultiAppendSuccess` - Successful append results for all streams
157-
- `MultiAppendFailure` - Specific exceptions for any failed operations
158-
159-
::: warning
160-
Event metadata in `EventData` must currently be valid JSON that can be deserialized into a
161-
`Dictionary<string, object?>`. This means any metadata you attach to an event should be structured as a JSON object, not as a primitive value or array.
162-
163-
For example, to encode metadata:
164-
```cs
165-
var metadata = JsonSerializer.SerializeToUtf8Bytes(new {
166-
Timestamp = DateTime.UtcNow,
167-
Source = "OrderProcessingSystem",
168-
Version = 1.0
169-
});
170-
```
171-
To decode metadata back into a dictionary:
172-
```cs
173-
var dictionary = MetadataDecoder.Decode(metadataBytes);
174-
```
175-
176-
This requirement ensures compatibility with KurrentDB's current metadata handling. In a future major release, this restriction will be lifted, allowing more flexible metadata formats.
177-
:::
178-
179-
Here's a basic example of appending events to multiple streams:
180-
181149
```cs
182150
using System.Text.Json;
183151

@@ -198,41 +166,19 @@ AppendStreamRequest[] requests = [
198166
)
199167
];
200168

201-
var result = await client.MultiStreamAppendAsync(requests);
202-
203-
if (result is MultiAppendSuccess { Successes: var successes })
204-
foreach (var item in successes)
205-
Console.WriteLine($"Stream '{item.Stream}' updated at position {item.Position}");
169+
await client.MultiStreamAppendAsync(requests);
206170
```
207171

208-
If the operation doesn't succeed, you should check if the result is a `MultiAppendFailure` and handle each failure case appropriately. This allows you to respond to specific errors, such as version conflicts, access issues, deleted streams, or transaction size limits. For example:
172+
The result returns the position of the last appended record in the transaction and a collection of responses for each stream appended in the transaction.
209173

174+
::: warning
175+
If you are storing metadata, it must currently be a valid JSON that can be deserialized into a
176+
`Dictionary<string, object?>`. This means any metadata you attach to an event should be structured as a JSON object, not as a primitive value or array.
177+
178+
When reading those events you can use the metadata decoder utility class to decode your metadata:
210179
```cs
211-
var result = await client.MultiStreamAppendAsync(requests);
212-
213-
if (result is MultiAppendFailure { Failures: var failures }) {
214-
foreach (var error in failures) {
215-
switch (error) {
216-
case WrongExpectedVersionException ex:
217-
Console.WriteLine($"Version conflict in stream: {ex.Message}");
218-
break;
219-
220-
case AccessDeniedException:
221-
Console.WriteLine("Access denied to one or more streams");
222-
break;
223-
224-
case StreamDeletedException ex:
225-
Console.WriteLine($"Stream was deleted: {ex.Message}");
226-
break;
227-
228-
case TransactionMaxSizeExceededException ex:
229-
Console.WriteLine($"Transaction too large: {ex.Message}");
230-
break;
231-
232-
default:
233-
Console.WriteLine($"Unexpected error: {error.Message}");
234-
break;
235-
}
236-
}
237-
}
180+
var dictionary = MetadataDecoder.Decode(metadataBytes);
238181
```
182+
183+
This requirement ensures compatibility with KurrentDB's current metadata handling, and the restriction will be lifted in the next major release.
184+
:::

src/KurrentDB.Client/Streams/Streams/Model/StreamsClientModel.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,27 @@ namespace KurrentDB.Client;
2020
[PublicAPI]
2121
public record AppendStreamRequest(string Stream, StreamState ExpectedState, IEnumerable<EventData> Messages);
2222

23+
/// <summary>
24+
/// Represents the outcome of an append operation.
25+
/// </summary>
26+
/// <param name="Stream">
27+
/// The name of the stream to which records were appended.
28+
/// </param>
29+
/// <param name="StreamRevision">
30+
/// The expected revision of the stream after the append operation.
31+
/// </param>
2332
[PublicAPI]
2433
public record AppendResponse(string Stream, long StreamRevision);
2534

2635
[PublicAPI]
2736
public readonly struct MultiStreamAppendResponse(long position, IEnumerable<AppendResponse>? responses = null) {
28-
public readonly long Position = position;
37+
/// <summary>
38+
/// The position of the last appended record in the transaction.
39+
/// </summary>
40+
public readonly long Position = position;
41+
42+
/// <summary>
43+
/// The collection of responses for each stream appended in the transaction.
44+
/// </summary>
2945
public readonly IEnumerable<AppendResponse>? Responses = responses;
3046
}

0 commit comments

Comments
 (0)