Setup
# pubspec.yaml
dependencies:
shelf: ^1.4.0
shelf_router: ^1.1.0
Basic Server
import 'dart:io';
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
Response _handler(Request request) {
return Response.ok('Hello, World!', headers: {'Content-Type': 'text/plain'});
}
void main() async {
var handler = const Pipeline()
.addMiddleware(logRequests())
.addHandler(_handler);
var server = await shelf_io.serve(handler, '0.0.0.0', 8080);
print('Server running on http://localhost:$${server.port}');
}
Routing
import 'package:shelf_router/shelf_router.dart';
void main() async {
var router = Router();
router.get('/', (Request req) => Response.ok('Welcome!'));
router.get('/hello/<name>', (Request req, String name) =>
Response.ok('Hello, $name!'));
router.get('/users', (Request req) => Response.ok('All users'));
router.post('/users', (Request req) async {
var body = await req.readAsString();
return Response.ok('Created: $body', headers: {'Content-Type': 'application/json'});
});
var handler = const Pipeline()
.addMiddleware(logRequests())
.addHandler(router.call);
await shelf_io.serve(handler, 'localhost', 8080);
print('Running on http://localhost:8080');
}
Middleware
// CORS middleware
Middleware corsMiddleware() {
return (Handler handler) {
return (Request request) async {
if (request.method == 'OPTIONS') {
return Response.ok('', headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
});
}
final response = await handler(request);
return response.change(headers: {
'Access-Control-Allow-Origin': '*',
});
};
};
}
// Auth middleware
Middleware authMiddleware(String secretKey) {
return (Handler handler) {
return (Request req) async {
var auth = req.headers['Authorization'];
if (auth == null || !auth.startsWith('Bearer ')) {
return Response.forbidden('Unauthorized');
}
return handler(req);
};
};
}
JSON REST API
import 'dart:convert';
import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf/shelf_io.dart' as io;
final _users = <int, Map<String, dynamic>>{
1: {'id': 1, 'name': 'Alice', 'email': 'alice@example.com'},
2: {'id': 2, 'name': 'Bob', 'email': 'bob@example.com'},
};
Response jsonResponse(dynamic data, {int status = 200}) => Response(
status,
body: jsonEncode(data),
headers: {'Content-Type': 'application/json'},
);
void main() async {
var router = Router()
..get('/users', (req) => jsonResponse(_users.values.toList()))
..get('/users/<id>', (req, String id) {
var user = _users[int.tryParse(id)];
return user != null ? jsonResponse(user) : Response.notFound('Not found');
})
..post('/users', (req) async {
var body = jsonDecode(await req.readAsString());
var id = _users.length + 1;
_users[id] = {'id': id, ...body};
return jsonResponse(_users[id], status: 201);
});
var handler = Pipeline().addMiddleware(logRequests()).addHandler(router.call);
await io.serve(handler, 'localhost', 8080);
print('API on http://localhost:8080');
}
🧠 Quiz
1. What Dart package provides HTTP server functionality?
- A) dart:http
- B) shelf ✅
- C) dart:server
- D) http_server
2. What does Pipeline().addMiddleware().addHandler() create?
- A) A router
- B) A chain of request handlers where middleware wraps the final handler ✅
- C) An async stream
- D) A web socket connection
Summary
Use the shelf package for server-side Dart HTTP servers. Define routes with shelf_router's Router. Chain middleware (logging, CORS, auth) with Pipeline().addMiddleware(). Return JSON with a helper that sets Content-Type: application/json. Start the server with shelf_io.serve(handler, host, port).