Expose-less ctrl done
This commit is contained in:
parent
0a9b5c118f
commit
650cf208fc
2 changed files with 85 additions and 3 deletions
59
example/controller.dart
Normal file
59
example/controller.dart
Normal file
|
@ -0,0 +1,59 @@
|
|||
import 'package:angel_container/mirrors.dart';
|
||||
import 'package:angel_framework/angel_framework.dart';
|
||||
import 'package:angel_framework/http.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
main() async {
|
||||
// Logging set up/boilerplate
|
||||
Logger.root.onRecord.listen(print);
|
||||
|
||||
// Create our server.
|
||||
var app = Angel(logger: Logger('angel'), reflector: MirrorsReflector());
|
||||
var http = AngelHttp(app);
|
||||
|
||||
await app.mountController<ArtistsController>();
|
||||
|
||||
// Simple fallback to throw a 404 on unknown paths.
|
||||
app.fallback((req, res) {
|
||||
throw AngelHttpException.notFound(
|
||||
message: 'Unknown path: "${req.uri.path}"',
|
||||
);
|
||||
});
|
||||
|
||||
app.errorHandler = (e, req, res) => e.toJson();
|
||||
|
||||
await http.startServer('127.0.0.1', 3000);
|
||||
print('Listening at ${http.uri}');
|
||||
app.dumpTree();
|
||||
}
|
||||
|
||||
class ArtistsController extends Controller {
|
||||
List index() {
|
||||
return ['Elvis', 'Stevie', 'Van Gogh'];
|
||||
}
|
||||
|
||||
String getById(int id, RequestContext req) {
|
||||
return 'You fetched ID: $id from IP: ${req.ip}';
|
||||
}
|
||||
|
||||
@Expose.post
|
||||
form(RequestContext req) async {
|
||||
// Deserialize the body into an artist.
|
||||
var artist = await req.deserializeBody((m) {
|
||||
return Artist(name: m['name'] as String ?? '(unknown name)');
|
||||
});
|
||||
|
||||
// Return it (it will be serialized to JSON).
|
||||
return artist;
|
||||
}
|
||||
}
|
||||
|
||||
class Artist {
|
||||
final String name;
|
||||
|
||||
Artist({this.name});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {'name': name};
|
||||
}
|
||||
}
|
|
@ -127,9 +127,31 @@ class Controller {
|
|||
|
||||
// If there is no path, reverse-engineer one.
|
||||
var path = exposeDecl.path;
|
||||
var httpMethod = exposeDecl.method ?? 'GET';
|
||||
if (path == null) {
|
||||
var parts = <String>[];
|
||||
parts.add(ReCase(method.name).snakeCase.replaceAll(_multiScore, '_'));
|
||||
var methodMatch = _methods.firstMatch(method.name);
|
||||
|
||||
if (methodMatch != null) {
|
||||
var rest = method.name.replaceAll(_methods, '');
|
||||
var restPath = ReCase(rest.isEmpty ? 'index' : rest)
|
||||
.snakeCase
|
||||
.replaceAll(_multiScore, '_');
|
||||
httpMethod = methodMatch[1].toUpperCase();
|
||||
|
||||
if (['index', 'by_id'].contains(restPath)) {
|
||||
parts.add('/');
|
||||
} else {
|
||||
parts.add(restPath);
|
||||
}
|
||||
} else {
|
||||
if (method.name == 'index') {
|
||||
parts.add('/');
|
||||
} else {
|
||||
parts.add(
|
||||
ReCase(method.name).snakeCase.replaceAll(_multiScore, '_'));
|
||||
}
|
||||
}
|
||||
|
||||
// Try to infer String, int, or double.
|
||||
for (var p in injection.required) {
|
||||
|
@ -149,8 +171,8 @@ class Controller {
|
|||
path = parts.join('/');
|
||||
}
|
||||
|
||||
routeMappings[name] = routable.addRoute(exposeDecl.method,
|
||||
exposeDecl.path, handleContained(reflectedMethod, injection),
|
||||
routeMappings[name] = routable.addRoute(
|
||||
httpMethod, path, handleContained(reflectedMethod, injection),
|
||||
middleware: middleware);
|
||||
}
|
||||
};
|
||||
|
@ -159,6 +181,7 @@ class Controller {
|
|||
/// Used to add additional routes to the router from within a [Controller].
|
||||
void configureRoutes(Routable routable) {}
|
||||
|
||||
static final RegExp _methods = RegExp(r'^(get|post|patch|delete)');
|
||||
static final RegExp _multiScore = RegExp(r'__+');
|
||||
|
||||
/// Finds the [Expose] declaration for this class.
|
||||
|
|
Loading…
Reference in a new issue