SwiftStack 0.3.0
dotnet add package SwiftStack --version 0.3.0
NuGet\Install-Package SwiftStack -Version 0.3.0
<PackageReference Include="SwiftStack" Version="0.3.0" />
<PackageVersion Include="SwiftStack" Version="0.3.0" />
<PackageReference Include="SwiftStack" />
paket add SwiftStack --version 0.3.0
#r "nuget: SwiftStack, 0.3.0"
#:package SwiftStack@0.3.0
#addin nuget:?package=SwiftStack&version=0.3.0
#tool nuget:?package=SwiftStack&version=0.3.0
SwiftStack
SwiftStack is an opinionated and easy way to build distributed systems — RESTful, message queue–oriented, or WebSocket–based — inspired by the elegant model shown in FastAPI (Python) but designed for C# developers who value clarity and speed.
MIT Licensed • No ceremony • Just build.
✨ New in v0.3.x
- WebSockets application support via
WebsocketsApp
- RabbitMQ resilient interfaces with on-disk indexing for recovery
🚀 Simple REST Example
<details> <summary>Click to expand</summary>
using SwiftStack;
class Program
{
static async Task Main(string[] args)
{
SwiftStackApp app = new SwiftStackApp("My test application");
app.Rest.Route("GET", "/", async (req) => "Hello world");
app.Rest.Route("POST", "/loopback", async (req) => req.Data);
app.Rest.Get("/search", async (req) =>
{
string query = req.Query["q"];
if (string.IsNullOrEmpty(query)) query = "no query provided";
int page = int.TryParse(req.Query["page"] as string, out int p) ? p : 1;
return new
{
Query = query,
Page = page,
Message = $"Searching for '{query}' on page {page}"
};
});
await app.Rest.Run();
}
}
</details>
🔐 REST Example with Authentication
<details> <summary>Click to expand</summary>
using SwiftStack;
class Program
{
static async Task Main(string[] args)
{
SwiftStackApp app = new SwiftStackApp("My secure app");
app.Rest.AuthenticationRoute = AuthenticationRoute;
app.Rest.Route("GET", "/authenticated", async (req) => "Hello, authenticated user", true);
await app.Rest.Run();
}
static async Task<AuthResult> AuthenticationRoute(HttpContextBase ctx)
{
if (ctx.Request.Authorization?.Username == "user" &&
ctx.Request.Authorization?.Password == "password")
{
ctx.Metadata = new { Authorized = true };
return AuthResult.Permit();
}
return AuthResult.Deny();
}
}
</details>
📨 RabbitMQ Example
SwiftStack includes first-class RabbitMQ support, including resilient producer/consumer and broadcaster/receiver patterns.
Resilient modes use on-disk index files to recover state across process restarts.
using SwiftStack;
using SwiftStack.RabbitMq;
// Initialize app and RabbitMQ integration
SwiftStackApp app = new SwiftStackApp("RabbitMQ Example");
RabbitMqApp rabbit = new RabbitMqApp(app);
// Define queue settings
QueueProperties queueProps = new QueueProperties
{
Hostname = "localhost",
Name = "demo-queue",
AutoDelete = true
};
// Create producer and consumer
var producer = new RabbitMqProducer<string>(app.Logging, queueProps, 1024 * 1024);
var consumer = new RabbitMqConsumer<string>(app.Logging, queueProps, true);
consumer.MessageReceived += (sender, e) =>
{
Console.WriteLine($"[Consumer] {e.Data}");
};
// Initialize and send
await producer.InitializeAsync();
await consumer.InitializeAsync();
for (int i = 1; i <= 5; i++)
{
await producer.SendMessage($"Message {i}", Guid.NewGuid().ToString());
await Task.Delay(500);
}
Resilient versions are identical except you use:
var producer = new ResilientRabbitMqProducer<string>(app.Logging, queueProps, "./producer.idx", 1024 * 1024);
var consumer = new ResilientRabbitMqConsumer<string>(app.Logging, queueProps, "./consumer.idx", 4, true);
and the same for broadcaster/receiver via:
var broadcaster = new RabbitMqBroadcaster<MyType>(...);
var receiver = new RabbitMqBroadcastReceiver<MyType>(...);
🔌 WebSockets Example
SwiftStack makes it trivial to stand up WebSocket servers with routing, default handlers, and direct server→client messaging.
using SwiftStack;
using SwiftStack.Websockets;
SwiftStackApp app = new SwiftStackApp("WebSockets Demo");
WebsocketsApp wsApp = new WebsocketsApp(app);
// Route for "echo"
wsApp.AddRoute("echo", async (msg, token) =>
{
await msg.RespondAsync($"Echo: {msg.DataAsString}");
});
// Default route
wsApp.DefaultRoute = async (msg, token) =>
{
await msg.RespondAsync("No route matched, sorry!");
};
// Start server
app.LoggingSettings.EnableConsole = true;
Task serverTask = wsApp.Run("127.0.0.1", 9006, CancellationToken.None);
// Example: sending server→client message after connect
wsApp.ClientConnected += async (sender, client) =>
{
await wsApp.WebsocketServer.SendAsync(client.Guid, "Welcome to the server!");
};
await serverTask;
Client (any WebSocket library works — here’s with System.Net.WebSockets
):
using var ws = new ClientWebSocket();
await ws.ConnectAsync(new Uri("ws://127.0.0.1:9006/echo"), CancellationToken.None);
await ws.SendAsync(Encoding.UTF8.GetBytes("Hello"), WebSocketMessageType.Text, true, CancellationToken.None);
📦 Installation
dotnet add package SwiftStack
📜 Version History
See CHANGELOG.md for details.
❤️ Donations
If you’d like to financially support development: see DONATIONS.md.
🖼 Logo
Thanks to pngall.com for the lightning icon.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- PersistentCollection (>= 2.0.12)
- RabbitMQ.Client (>= 7.1.2)
- SerializationHelper (>= 2.0.3)
- SyslogLogging (>= 2.0.8)
- Watson (>= 6.3.9)
- WatsonWebsocket (>= 4.1.5)
-
.NETStandard 2.1
- PersistentCollection (>= 2.0.12)
- RabbitMQ.Client (>= 7.1.2)
- SerializationHelper (>= 2.0.3)
- SyslogLogging (>= 2.0.8)
- Watson (>= 6.3.9)
- WatsonWebsocket (>= 4.1.5)
-
net8.0
- PersistentCollection (>= 2.0.12)
- RabbitMQ.Client (>= 7.1.2)
- SerializationHelper (>= 2.0.3)
- SyslogLogging (>= 2.0.8)
- Watson (>= 6.3.9)
- WatsonWebsocket (>= 4.1.5)
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 |
---|---|---|
0.3.0 | 25 | 8/15/2025 |
0.2.4 | 177 | 7/26/2025 |
0.2.3 | 192 | 7/26/2025 |
0.2.2 | 398 | 7/25/2025 |
0.2.1 | 484 | 7/23/2025 |
0.2.0 | 118 | 7/13/2025 |
0.1.20 | 214 | 5/14/2025 |
0.1.19 | 143 | 4/10/2025 |
0.1.18 | 102 | 4/4/2025 |
0.1.16 | 153 | 4/1/2025 |
0.1.15 | 142 | 4/1/2025 |
0.1.13 | 143 | 4/1/2025 |
0.1.12 | 144 | 3/30/2025 |
0.1.11 | 137 | 3/30/2025 |
0.1.10 | 141 | 3/30/2025 |
0.1.9 | 127 | 3/30/2025 |
0.1.8 | 66 | 3/29/2025 |
0.1.7 | 68 | 3/29/2025 |
0.1.5 | 85 | 3/29/2025 |
0.1.4 | 76 | 3/21/2025 |
0.1.3 | 135 | 3/12/2025 |
0.1.2 | 90 | 2/25/2025 |
0.1.1 | 84 | 2/25/2025 |
0.1.0 | 91 | 2/24/2025 |
Initial release