Sparky: A Lightweight Framework for Building REST and WebSocket APIs with JWT Authentication
Published on by Flutter News Hub
Sparky is a Dart package that simplifies the development of RESTful and WebSocket APIs with support for JWT authentication. It offers a range of features to enhance the development process.
Features
- Comprehensive logging system
- WebSocket support
- JWT authentication
- Customizable pipelines for pre- and post-processing of requests and responses
Creating Routes
Creating a Simple Route
Using a custom route constructor, you can specify the HTTP method or use the default constructor and customize the route later.
import 'package:sparky/sparky.dart';
void main() {
// Create a route with a custom middleware that accepts all request data and returns a response.
final route1 = RouteHttp.get('/test', middleware: (request) async {
return Response.ok(body: 'Hello, world!');
});
// Initialize Sparky with a list of routes.
Sparky.server(routes: [route1]);
}
Creating a Route from a Class
Routes can also be created as classes, providing more control over the route's behavior and configuration, such as WebSocket support and accepted HTTP methods.
import 'package:sparky/sparky.dart';
class RouteTest extends Route {
RouteTest() : super('/test', middleware: (request) async {
return Response.ok(body: 'test');
}, acceptedMethods: [AcceptedMethods.get, AcceptedMethods.post]);
}
class RouteSocket extends Route {
RouteSocket() : super('/socket', middlewareWebSocket: (WebSocket webSocket) async {
webSocket.listen((event) {
print(event);
}, onDone: () {
webSocket.close();
});
});
}
void main() {
// Initialize Sparky with a list of routes.
Sparky.server(routes: [RouteTest(), RouteSocket()]);
}
Customizing IP and Port
You can specify the IP address and port used by Sparky.
void main() {
Sparky.server(routes: [...], ip: '0.0.0.0', port: 8080);
}
Creating Pipelines
Pipelines allow you to add middleware to be executed before or after the main route middleware.
void main() {
Sparky.server(
routes: [...],
// Executes after the route middleware.
pipelineAfter: Pipeline()..add((request) async => null)..add((request) async => null),
// Executes before the route middleware.
pipelineBefore: Pipeline()..add((request) async { ... }),
);
}
Logging System
Sparky provides a configurable logging system.
void main() {
Sparky.server(
routes: [...],
logConfig: LogConfig.showAndWriteLogs,
logType: LogType.all
);
}
Using WebSockets
WebSocket routes can be created with the RouteWebSocket class and added to the list of routes.
void main() {
final websocket = RouteWebSocket(
'/test',
middlewareWebSocket: (WebSocket socket) async {
socket.add('Hello, world!');
socket.listen((event) {
print(event);
}, onDone: () {
socket.close();
});
},
);
Sparky.server(routes: [websocket]);
}
Implementing JWT Authentication
Using JWT authentication, you can protect routes by verifying a token sent in the request.
import 'package:sparky/sparky.dart';
void main() {
final authJwt = AuthJwt(secretKey: 'secretKey');
final login = RouteHttp.get('/login', middleware: (HttpRequest request) async {
final token = authJwt.generateToken({'username': 'username'});
return Response.ok(body: '{"token":"$token"}');
});
Sparky.server(
routes: [login],
pipelineBefore: Pipeline()
..add((HttpRequest request) async {
if (request.requestedUri.path == '/login') {
return null;
} else {
if (request.headers['token'] != null) {
if (authJwt.verifyToken(request.headers['token']!.first)) {
return null;
} else {
return Response.unauthorized(body: 'Unauthorized');
}
} else {
return Response.unauthorized(body: 'Send token in the header');
}
}
}),
);
}
Performance Optimization
For improved performance, compile your Dart code to an executable using the following command:
dart compile exe main.dart
Future Vision
Sparky aims to remain simple and user-friendly. Future updates will focus on adding support for executing specific routes in separate isolates for enhanced performance. Contributions to the open-source project are always welcome.