Worked out some kinks in routing and hooked services. Services can use middleware.
This commit is contained in:
parent
80c6118544
commit
897a09d359
5 changed files with 98 additions and 33 deletions
|
@ -73,7 +73,7 @@ class RequestContext extends Extensible {
|
|||
context.contentType = request.headers.contentType;
|
||||
context.remoteAddress = request.connectionInfo.remoteAddress;
|
||||
context.params = parameters;
|
||||
context.path = request.uri.toString();
|
||||
context.path = request.uri.toString().replaceAll("?" + request.uri.query, "").replaceAll(new RegExp(r'\/+$'), '');
|
||||
context.route = sourceRoute;
|
||||
context.session = request.session;
|
||||
context.underlyingRequest = request;
|
||||
|
|
|
@ -52,7 +52,7 @@ class Angel extends Routable {
|
|||
|
||||
server.listen((HttpRequest request) async {
|
||||
String req_url =
|
||||
request.uri.toString().replaceAll(new RegExp(r'\/+$'), '');
|
||||
request.uri.toString().replaceAll("?" + request.uri.query, "").replaceAll(new RegExp(r'\/+$'), '');
|
||||
if (req_url.isEmpty) req_url = '/';
|
||||
RequestContext req = await RequestContext.from(request, {}, this, null);
|
||||
ResponseContext res = await ResponseContext.from(request.response, this);
|
||||
|
@ -95,7 +95,7 @@ class Angel extends Routable {
|
|||
if (!canContinue) break;
|
||||
if (route.matcher.hasMatch(req_url) &&
|
||||
(request.method == route.method || route.method == '*')) {
|
||||
req.params = route.parseParameters(request.uri.toString());
|
||||
req.params = route.parseParameters(req_url);
|
||||
req.route = route;
|
||||
|
||||
for (var handler in route.handlers) {
|
||||
|
|
|
@ -60,22 +60,46 @@ class Service extends Routable {
|
|||
Service() : super() {
|
||||
Map restProvider = {'provider': Providers.REST};
|
||||
|
||||
Middleware indexMiddleware = _getAnnotation(this.index, Middleware);
|
||||
get('/', (req, res) async {
|
||||
return await this.index(mergeMap([req.query, restProvider]));
|
||||
});
|
||||
}, middleware: (indexMiddleware == null) ? [] : indexMiddleware.handlers);
|
||||
|
||||
post('/', (req, res) async => await this.create(req.body, restProvider));
|
||||
Middleware createMiddleware = _getAnnotation(this.create, Middleware);
|
||||
post('/', (req, res) async => await this.create(req.body, restProvider),
|
||||
middleware:
|
||||
(createMiddleware == null) ? [] : createMiddleware.handlers);
|
||||
|
||||
get('/:id', (req, res) async =>
|
||||
await this.read(req.params['id'], mergeMap([req.query, restProvider])));
|
||||
Middleware readMiddleware = _getAnnotation(this.read, Middleware);
|
||||
|
||||
patch('/:id', (req, res) async => await this.modify(
|
||||
req.params['id'], req.body, restProvider));
|
||||
get(
|
||||
'/:id',
|
||||
(req, res) async => await this
|
||||
.read(req.params['id'], mergeMap([req.query, restProvider])),
|
||||
middleware: (readMiddleware == null) ? [] : readMiddleware.handlers);
|
||||
|
||||
post('/:id', (req, res) async => await this.update(
|
||||
req.params['id'], req.body, restProvider));
|
||||
Middleware modifyMiddleware = _getAnnotation(this.modify, Middleware);
|
||||
patch(
|
||||
'/:id',
|
||||
(req, res) async =>
|
||||
await this.modify(req.params['id'], req.body, restProvider),
|
||||
middleware:
|
||||
(modifyMiddleware == null) ? [] : modifyMiddleware.handlers);
|
||||
|
||||
delete('/:id', (req, res) async => await this.remove(
|
||||
req.params['id'], mergeMap([req.query, restProvider])));
|
||||
Middleware updateMiddleware = _getAnnotation(this.update, Middleware);
|
||||
post(
|
||||
'/:id',
|
||||
(req, res) async =>
|
||||
await this.update(req.params['id'], req.body, restProvider),
|
||||
middleware:
|
||||
(updateMiddleware == null) ? [] : updateMiddleware.handlers);
|
||||
|
||||
Middleware removeMiddleware = _getAnnotation(this.remove, Middleware);
|
||||
delete(
|
||||
'/:id',
|
||||
(req, res) async => await this
|
||||
.remove(req.params['id'], mergeMap([req.query, restProvider])),
|
||||
middleware:
|
||||
(removeMiddleware == null) ? [] : removeMiddleware.handlers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,29 +6,32 @@ class HookedService extends Service {
|
|||
final Service inner;
|
||||
|
||||
HookedServiceEventDispatcher beforeIndexed =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher beforeRead = new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher beforeCreated =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher beforeModified =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher beforeUpdated =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher beforeRemoved =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher afterIndexed =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher afterRead = new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher afterCreated =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher afterModified =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher afterUpdated =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
HookedServiceEventDispatcher afterRemoved =
|
||||
new HookedServiceEventDispatcher();
|
||||
new HookedServiceEventDispatcher();
|
||||
|
||||
HookedService(Service this.inner) : super() {}
|
||||
HookedService(Service this.inner) {
|
||||
// Clone all routes, including middleware
|
||||
routes..clear()..addAll(inner.routes);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List> index([Map params]) async {
|
||||
|
|
|
@ -9,6 +9,14 @@ testMiddlewareMetadata(RequestContext req, ResponseContext res) async {
|
|||
return "This should not be shown.";
|
||||
}
|
||||
|
||||
class QueryService extends Service {
|
||||
@override
|
||||
@Middleware(const ['intercept_service', 'interceptor'])
|
||||
read(id, [Map params]) {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
||||
main() {
|
||||
group('routing', () {
|
||||
Angel angel;
|
||||
|
@ -22,10 +30,16 @@ main() {
|
|||
nested = new Angel();
|
||||
todos = new Angel();
|
||||
|
||||
angel.registerMiddleware('interceptor', (req, res) async {
|
||||
res.write('Middleware');
|
||||
return false;
|
||||
});
|
||||
angel
|
||||
..registerMiddleware('interceptor', (req, res) async {
|
||||
res.write('Middleware');
|
||||
return false;
|
||||
})
|
||||
..registerMiddleware('intercept_service',
|
||||
(RequestContext req, res) async {
|
||||
print("Intercepting a service!");
|
||||
return true;
|
||||
});
|
||||
|
||||
todos.get('/action/:action', (req, res) => res.json(req.params));
|
||||
nested.post('/ted/:route', (req, res) => res.json(req.params));
|
||||
|
@ -37,12 +51,25 @@ main() {
|
|||
angel.post('/lambda', (req, res) => req.body);
|
||||
angel.use('/nes', nested);
|
||||
angel.use('/todos/:id', todos);
|
||||
angel.get('/greet/:name', (RequestContext req, res) async => "Hello ${req.params['name']}").as('Named routes');
|
||||
angel
|
||||
.get('/greet/:name',
|
||||
(RequestContext req, res) async => "Hello ${req.params['name']}")
|
||||
.as('Named routes');
|
||||
angel.get('/named', (req, ResponseContext res) async {
|
||||
res.redirectTo('Named routes', {'name': 'tests'});
|
||||
});
|
||||
angel.get('/log', (RequestContext req, res) async {
|
||||
print("Query: ${req.query}");
|
||||
return "Logged";
|
||||
});
|
||||
angel.use('/query', new QueryService());
|
||||
angel.get('*', 'MJ');
|
||||
|
||||
print("DUMPING ROUTES: ");
|
||||
for (Route route in angel.routes) {
|
||||
print("${route.method} ${route.path} - ${route.handlers}");
|
||||
}
|
||||
|
||||
client = new http.Client();
|
||||
await angel.startServer(InternetAddress.LOOPBACK_IP_V4, 0);
|
||||
url = "http://${angel.httpServer.address.host}:${angel.httpServer.port}";
|
||||
|
@ -97,8 +124,8 @@ main() {
|
|||
test('Can serialize function result as JSON', () async {
|
||||
Map headers = {'Content-Type': 'application/json'};
|
||||
String postData = god.serialize({'it': 'works'});
|
||||
var response = await client.post(
|
||||
"$url/lambda", headers: headers, body: postData);
|
||||
var response =
|
||||
await client.post("$url/lambda", headers: headers, body: postData);
|
||||
expect(god.deserialize(response.body)['it'], equals('works'));
|
||||
});
|
||||
|
||||
|
@ -119,5 +146,16 @@ main() {
|
|||
print(response.body);
|
||||
expect(god.deserialize(response.body), equals('Hello tests'));
|
||||
});
|
||||
|
||||
test('Match routes, even with query params', () async {
|
||||
var response =
|
||||
await client.get("$url/log?foo=bar&bar=baz&baz.foo=bar&baz.bar=foo");
|
||||
print(response.body);
|
||||
expect(god.deserialize(response.body), equals('Logged'));
|
||||
|
||||
response = await client.get("$url/query/foo?bar=baz");
|
||||
print(response.body);
|
||||
expect(response.body, equals("Middleware"));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue