Expose-less ctrl done

This commit is contained in:
thosakwe 2019-07-17 15:48:02 -04:00
parent 0a9b5c118f
commit 650cf208fc
2 changed files with 85 additions and 3 deletions

59
example/controller.dart Normal file
View 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};
}
}

View file

@ -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.