โก Supafast
Express.js-inspired backend framework for Dart
Supafast is a lightweight, Express.js-inspired HTTP framework for Dart that makes building backend APIs fast and enjoyable.
โจ Features
- ๐ Express.js-like API - Familiar routing and middleware patterns
- โก Zero Dependencies - Built on pure
dart:iofor maximum performance - ๐ง Type Safe - Full Dart type safety throughout
- ๐งช Testing Ready - Built-in testing utilities
- ๐ Middleware Support - Extensible middleware system
- ๐ฆ Production Ready - Comprehensive error handling and logging
๐ Quick Start
Installation
dependencies:
supafast: ^0.1.0
Hello World
import 'package:supafast/supafast.dart';
void main() async {
final app = Supafast();
app.get('/', (req, res) => res.send('Hello, Supafast! โก'));
await app.listen(3000);
print('๐ Server running on http://localhost:3000');
}
With Middleware
import 'package:supafast/supafast.dart';
void main() async {
final app = Supafast();
// Add middleware
app.use(cors());
app.use(logger());
app.use(bodyParser());
// Define routes
app.get('/users/:id', (req, res) {
final userId = req.params['id'];
return res.json({'userId': userId, 'name': 'John Doe'});
});
app.post('/users', (req, res) {
final userData = req.body;
return res.status(201).json({'message': 'User created', 'data': userData});
});
// Error handling
app.use(errorHandler());
await app.listen(3000);
print('๐ Server running on http://localhost:3000');
}
๐ Core Concepts
Routing
Supafast uses Express.js-style routing:
// HTTP methods
app.get('/users', handler);
app.post('/users', handler);
app.put('/users/:id', handler);
app.delete('/users/:id', handler);
app.patch('/users/:id', handler);
// Path parameters
app.get('/users/:id/posts/:postId', (req, res) {
final userId = req.params['id'];
final postId = req.params['postId'];
// ...
});
// Query parameters
app.get('/search', (req, res) {
final query = req.query['q'];
final limit = int.tryParse(req.query['limit'] ?? '10') ?? 10;
// ...
});
Request Object
app.post('/data', (req, res) async {
// Path parameters
final id = req.params['id'];
// Query parameters
final filter = req.query['filter'];
// Headers
final authHeader = req.header('authorization');
final contentType = req.contentType;
// Body (requires bodyParser middleware)
final jsonData = req.body; // Parsed JSON/form data
final rawBody = await req.rawBody; // Raw string
// Cookies
final sessionId = req.cookie('sessionId');
// Request info
final userAgent = req.userAgent;
final isSecure = req.isSecure;
final clientIP = req.ip;
});
Response Object
app.get('/api/data', (req, res) async {
// Status codes
res.status(201);
// Headers
res.header('X-API-Version', '1.0');
res.contentType('application/json');
// Cookies
res.cookie('sessionId', 'abc123', maxAge: 3600);
// Responses
return res.send('Plain text');
return res.json({'key': 'value'});
return res.html('<h1>Hello</h1>');
return res.file('/path/to/file.pdf');
return res.redirect('/other-page');
// Error responses
return res.notFound('Resource not found');
return res.badRequest('Invalid data');
return res.serverError('Something went wrong');
});
Middleware
// Global middleware
app.use(cors());
app.use(logger());
app.use(bodyParser());
// Route-specific middleware
app.get('/protected', [authMiddleware], (req, res) {
return res.json({'message': 'Protected resource'});
});
// Custom middleware
Middleware customAuth() {
return (req, res, next) async {
final token = req.header('authorization');
if (token == null) {
return res.unauthorized('Missing auth token');
}
// Add user to request
req.locals['user'] = {'id': '123', 'name': 'John'};
await next(); // Continue to next middleware/handler
};
}
Error Handling
// Global error handler (should be last middleware)
app.use(errorHandler());
// Throwing errors in handlers
app.get('/error-demo', (req, res) {
throw HttpException(400, 'Something went wrong');
// or
throw HttpException.badRequest('Invalid input');
});
// Custom error handler
app.use((req, res, next) async {
try {
await next();
} catch (error) {
if (error is CustomException) {
return res.status(422).json({'error': error.message});
}
rethrow; // Let default error handler deal with it
}
});
Nested Routing
// Create sub-router
final apiRouter = Router();
apiRouter.get('/users', getUsersHandler);
apiRouter.post('/users', createUserHandler);
final adminRouter = Router();
adminRouter.use(adminAuthMiddleware); // Apply auth to all admin routes
adminRouter.get('/stats', getStatsHandler);
// Mount routers
app.mount('/api/v1', apiRouter);
app.mount('/admin', adminRouter);
// Results in:
// GET /api/v1/users
// POST /api/v1/users
// GET /admin/stats
๐งช Testing
Supafast includes comprehensive testing utilities:
import 'package:test/test.dart';
import 'package:supafast/supafast.dart';
import 'package:supafast/testing.dart';
void main() {
group('API Tests', () {
late Supafast app;
late TestApp testApp;
setUp(() async {
app = Supafast();
testApp = TestApp(app);
app.get('/hello', (req, res) => res.send('Hello'));
app.post('/data', (req, res) => res.json(req.body));
await testApp.start();
});
tearDown(() => testApp.close());
test('GET /hello returns hello message', () async {
final response = await testApp.get('/hello').send();
expect(response.statusCode, 200);
expect(response.body, 'Hello');
});
test('POST /data echoes JSON', () async {
final testData = {'name': 'John'};
await testApp
.post('/data')
.json(testData)
.expect(200)
.expectJson(testData);
});
});
}
๐ Built-in Middleware
CORS
app.use(cors()); // Allow all origins
app.use(cors(
origins: ['https://myapp.com'],
methods: ['GET', 'POST'],
credentials: true,
));
Logging
app.use(logger()); // Basic request logging
app.use(compactLogger()); // Compact format
app.use(devLogger()); // Detailed logging for development
Body Parsing
app.use(bodyParser()); // Parse JSON and form data
app.use(jsonParser()); // JSON only
app.use(urlencodedParser()); // Form data only
Static Files
app.use(serveStatic('public')); // Serve files from public/
app.use(serveStatic('assets', StaticOptions(
index: 'index.html',
maxAge: 3600, // 1 hour cache
)));
Error Handling
app.use(errorHandler()); // Basic error handling
app.use(devErrorHandler()); // Include stack traces
app.use(prodErrorHandler()); // Production-safe errors
๐ฏ Examples
Check out the examples/ directory:
- Basic Server - Simple HTTP server
- REST API - Full CRUD API with middleware
๐ API Reference
Supafast Class
get(path, handler, [middleware])- Register GET routepost(path, handler, [middleware])- Register POST routeput(path, handler, [middleware])- Register PUT routedelete(path, handler, [middleware])- Register DELETE routepatch(path, handler, [middleware])- Register PATCH routeoptions(path, handler, [middleware])- Register OPTIONS routehead(path, handler, [middleware])- Register HEAD routeall(path, handler, [middleware])- Register route for all methodsuse(middleware)- Add global middlewaremount(prefix, router)- Mount sub-routerlisten(port, {hostname})- Start HTTP serverclose({force})- Stop HTTP server
Request Properties
method- HTTP method (GET, POST, etc.)path- Request path without query stringuri- Complete URIparams- Path parameters (Map<String, String>)query- Query parameters (Map<String, String>)headers- HTTP headersbody- Parsed request bodycookies- Request cookiesip- Client IP addressuserAgent- User-Agent headerisSecure- Whether request is HTTPSlocals- Custom data storage
Response Methods
status(code)- Set status codeheader(name, value)- Set headercookie(name, value, options)- Set cookiesend(text)- Send text responsejson(data)- Send JSON responsehtml(html)- Send HTML responsefile(path)- Send fileredirect(url, status)- Redirect requestnotFound(message)- Send 404 errorbadRequest(message)- Send 400 errorunauthorized(message)- Send 401 errorserverError(message)- Send 500 error
๐ค Contributing
Contributions are welcome! Here's how you can help:
- Report bugs - Open an issue with reproduction steps
- Suggest features - Share your ideas for improvements
- Submit PRs - Fix bugs or implement features
- Write docs - Help improve documentation
- Create examples - Show off what you've built
Development Setup
git clone https://github.com/supafast-dart/supafast.git
cd supafast/packages/supafast
dart pub get
dart test
๐ License
MIT License - see LICENSE file for details.
๐ Links
- GitHub: supafast-dart/supafast
- Pub.dev: pub.dev/packages/supafast
- Examples: examples/
- Issues: GitHub Issues
Built with โค๏ธ for the Dart community
Making backend development supafast โก