sirius_backend 2.3.10
sirius_backend: ^2.3.10 copied to clipboard
Sirius is a lightweight yet powerful Dart backend framework designed for building fast, scalable, and structured HTTP & WebSocket APIs.
Sirius β‘ β A Lightweight Dart Backend Framework #
Sirius is a lightweight, expressive, and fast HTTP & WebSocket backend framework built entirely with Dart.
It features powerful routing, composable wrapper middlewares, validation, and lifecycle hooks.
π Features #
- β‘ Simple, expressive routing (
GET,POST,PUT,PATCH,DELETE) - π§± Wrapper middleware via
.wrap()for lifecycle-level logic (e.g. logging, timing) - π Grouped routes for modular structure
- π Validation with nested object and list support
- π WebSocket routing support
- π‘ Built on top of
dart:iofor raw performance
π¦ Installation #
dependencies:
sirius_backend: ^2.3.10
Then run:
dart pub get
π οΈ Basic Usage #
import 'package:sirius_backend/sirius_backend.dart';
void main() async {
final sirius = Sirius();
sirius.get('/hello', (req) async {
return Response.send({'message': 'Hello from Sirius!'});
});
await sirius.start(port: 3000);
}
π Routing #
sirius.get('/users', userController.getUsersHandler);
sirius.post('/users', userController.createUserHandler);
sirius.put('/users/:id', userController.updateUserHandler);
sirius.delete('/users/:id', userController.deleteUserHandler);
Grouped Routes #
sirius.group('/api', (router) {
router.get('/status', (req) async => Response.send({'ok': true}));
});
π Wrapper Middleware (NEW in 2.0) #
Wrappers allow full control over the request lifecycle for tasks like logging, auth, timing, etc.
class TimerWrapper extends Wrapper {
@override
Future<Response> handle(Request request, Future<Response> Function() nextHandler) async {
final start = DateTime.now();
final response = await nextHandler();
final end = DateTime.now();
print("Duration: ${end.difference(start)}");
return response;
}
}
Register wrapper globally:
sirius.wrap(TimerWrapper().handle);
Or for a single route:
sirius.get('/dashboard', controller.dashboardHandler, wrappers: [TimerWrapper().handle]);
π§Ύ Request Object #
final id = request.pathVariable('id');
final name = request.jsonValue('name');
final headers = request.headers;
final method = request.method;
final userData = request.getContextData; // Passed via middleware
π§ Request Lifecycle Flow #
Incoming Request
βββ Global Wrapper (Entry)
βββ Route Wrapper (Entry)
βββ Route Handler
βββ Route Wrapper (Exit)
βββ Global Wrapper (Exit)
βββ Response Sent
1οΈβ£ Incoming Request
β
2οΈβ£ Global Wrapper (Entry)
β
3οΈβ£ Route Wrapper (Entry)
β
4οΈβ£ Route Handler (your main logic)
β
5οΈβ£ Route Wrapper (Exit)
β
6οΈβ£ Global Wrapper (Exit)
β
7οΈβ£ π’ Response Sent
β Validation #
Basic Validation #
final validator = Validator(request, {
'name': ValidationRules(required: required(message: "Name is required")),
'age': ValidationRules(minNumber: minNumber(18)),
});
if (!validator.validate()) {
return Response.send(validator.getAllErrors, statusCode: 400);
}
Nested Object Validation #
'address': ValidationRules(
dataType: dataType(DataTypes.MAP),
childMap: {
'street': ValidationRules(required: required()),
'zip': ValidationRules(minLength: minLength(5)),
},
)
List Validation #
'items': ValidationRules(
dataType: dataType(DataTypes.LIST),
childList: [
ValidationRules(required: required(message: "Item is required")),
],
)
Validate Every List Element with Same Rules #
'ids': ValidationRules(
dataType: dataType(DataTypes.LIST),
childList: ValidationRules(
required: required(),
dataType: dataType(DataTypes.NUMBER),
).forEachElement(),
)
π€ Response API #
return Response.send({"message": "Success"});
return Response.send({"error": "Unauthorized"}, statusCode: 401);
return Response.sendJson({"error": "Unauthorized"}, statusCode: 401);
You can also override headers:
return Response.send({'ok': true}, overrideHeaders: (headers) {
headers.set('x-powered-by', 'Sirius');
});
π WebSocket Support #
sirius.webSocket('/chat', (request, socketConn) {
final connId = socketConn.getId;
print("Client connected: $connId");
// Respond to a custom event
socketConn.onEvent("ping", (data) {
print("Received ping: $data");
socketConn.sendEvent("pong", {
"message": "Pong received!",
"echo": data,
});
});
// Listen to raw messages (not event-based)
socketConn.onData((msg) {
print("Raw message: $msg");
socketConn.sendData("Echo: $msg");
});
// Handle disconnection
socketConn.onDisconnect(() {
print("Client disconnected: $connId");
});
});
π§± Advanced Usage: Route Composition #
sirius.get(
'/secure-data',
secureDataHandler,
wrappers: [
TimerWrapper().handle,
AuthWrapper().handle,
],
);
π License #
MIT License β free for commercial and personal use.
π€ Contributing #
Pull requests, issues, and feature suggestions are welcome. Letβs make backend development in Dart delightful!