This commit is contained in:
thosakwe 2017-02-12 19:38:33 -05:00
parent 6eebc7afa8
commit 07025403f4
10 changed files with 120 additions and 45 deletions

View file

@ -1,6 +1,6 @@
# angel_framework # angel_framework
[![pub 1.0.0-dev.54](https://img.shields.io/badge/pub-1.0.0--dev.54-red.svg)](https://pub.dartlang.org/packages/angel_framework) [![pub 1.0.0-dev.55](https://img.shields.io/badge/pub-1.0.0--dev.55-red.svg)](https://pub.dartlang.org/packages/angel_framework)
[![build status](https://travis-ci.org/angel-dart/framework.svg)](https://travis-ci.org/angel-dart/framework) [![build status](https://travis-ci.org/angel-dart/framework.svg)](https://travis-ci.org/angel-dart/framework)
Core libraries for the Angel Framework. Core libraries for the Angel Framework.

8
lib/common.dart Normal file
View file

@ -0,0 +1,8 @@
/// Represents arbitrary data, with an associated ID and timestamps.
class Model {
String id;
DateTime createdAt;
DateTime updatedAt;
Model({this.id, this.createdAt, this.updatedAt});
}

View file

@ -36,10 +36,14 @@ AngelConfigurer hookAllServices(callback(Service service)) {
HookedServiceEventListener toJson() { HookedServiceEventListener toJson() {
return (HookedServiceEvent e) { return (HookedServiceEvent e) {
normalize(obj) { normalize(obj) {
if (obj != null && obj is! Map) obj = god.serializeObject(obj); if (obj != null && obj is! Map) return god.serializeObject(obj);
return obj;
} }
normalize(e.isBefore ? e.data : e.result); if (e.isBefore) {
return e.data = normalize(e.data);
} else
e.result = normalize(e.result);
}; };
} }
@ -49,10 +53,14 @@ HookedServiceEventListener toType(Type type) {
return (HookedServiceEvent e) { return (HookedServiceEvent e) {
normalize(obj) { normalize(obj) {
if (obj != null && obj.runtimeType != type) if (obj != null && obj.runtimeType != type)
obj = god.deserializeDatum(obj, outputType: type); return god.deserializeDatum(obj, outputType: type);
return obj;
} }
normalize(e.isBefore ? e.data : e.result); if (e.isBefore) {
return e.data = normalize(e.data);
} else
e.result = normalize(e.result);
}; };
} }

View file

@ -1,6 +1,9 @@
library angel_framework.defs; library angel_framework.defs;
import '../common.dart';
export '../common.dart';
/// Represents data that can be serialized into a MemoryService; /// Use [Model] instead.
@deprecated
class MemoryModel { class MemoryModel {
int id; int id;
} }

View file

@ -117,7 +117,10 @@ class HookedService extends Service {
Middleware indexMiddleware = getAnnotation(inner.index, Middleware); Middleware indexMiddleware = getAnnotation(inner.index, Middleware);
get('/', (req, res) async { get('/', (req, res) async {
return await this.index(mergeMap([req.query, restProvider])); return await this.index(mergeMap([
{'query': req.query},
restProvider
]));
}, },
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
@ -126,8 +129,12 @@ class HookedService extends Service {
Middleware createMiddleware = getAnnotation(inner.create, Middleware); Middleware createMiddleware = getAnnotation(inner.create, Middleware);
post( post(
'/', '/',
(req, res) async => (req, res) async => await this.create(
await this.create(req.body, mergeMap([req.query, restProvider])), req.body,
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll( ..addAll(
@ -137,8 +144,12 @@ class HookedService extends Service {
get( get(
'/:id', '/:id',
(req, res) async => await this (req, res) async => await this.read(
.read(toId(req.params['id']), mergeMap([req.query, restProvider])), toId(req.params['id']),
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll((readMiddleware == null) ? [] : readMiddleware.handlers)); ..addAll((readMiddleware == null) ? [] : readMiddleware.handlers));
@ -146,8 +157,13 @@ class HookedService extends Service {
Middleware modifyMiddleware = getAnnotation(inner.modify, Middleware); Middleware modifyMiddleware = getAnnotation(inner.modify, Middleware);
patch( patch(
'/:id', '/:id',
(req, res) async => await this.modify(toId(req.params['id']), req.body, (req, res) async => await this.modify(
mergeMap([req.query, restProvider])), toId(req.params['id']),
req.body,
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll( ..addAll(
@ -156,8 +172,13 @@ class HookedService extends Service {
Middleware updateMiddleware = getAnnotation(inner.update, Middleware); Middleware updateMiddleware = getAnnotation(inner.update, Middleware);
post( post(
'/:id', '/:id',
(req, res) async => await this.update(toId(req.params['id']), req.body, (req, res) async => await this.update(
mergeMap([req.query, restProvider])), toId(req.params['id']),
req.body,
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll( ..addAll(
@ -167,7 +188,11 @@ class HookedService extends Service {
delete( delete(
'/:id', '/:id',
(req, res) async => await this.remove( (req, res) async => await this.remove(
toId(req.params['id']), mergeMap([req.query, restProvider])), toId(req.params['id']),
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll( ..addAll(
@ -251,7 +276,7 @@ class HookedService extends Service {
} }
@override @override
Future<List> index([Map _params]) async { Future index([Map _params]) async {
var params = _stripReq(_params); var params = _stripReq(_params);
HookedServiceEvent before = await beforeIndexed._emit( HookedServiceEvent before = await beforeIndexed._emit(
new HookedServiceEvent._base(false, _getRequest(_params), new HookedServiceEvent._base(false, _getRequest(_params),

View file

@ -4,7 +4,7 @@ import 'dart:async';
import 'dart:mirrors'; import 'dart:mirrors';
import 'package:json_god/json_god.dart' as god; import 'package:json_god/json_god.dart' as god;
import 'package:merge_map/merge_map.dart'; import 'package:merge_map/merge_map.dart';
import '../defs.dart'; import '../../common.dart';
import 'angel_http_exception.dart'; import 'angel_http_exception.dart';
import 'service.dart'; import 'service.dart';
@ -24,17 +24,17 @@ class MemoryService<T> extends Service {
final bool allowRemoveAll; final bool allowRemoveAll;
//// The data contained in this service. //// The data contained in this service.
final Map<int, MemoryModel> items = {}; final Map<int, Model> items = {};
MemoryService({this.allowRemoveAll: false}) : super() { MemoryService({this.allowRemoveAll: false}) : super() {
if (!reflectType(T).isAssignableTo(reflectType(MemoryModel))) { if (!reflectType(T).isAssignableTo(reflectType(Model))) {
throw new Exception( throw new Exception(
"MemoryServices only support classes that inherit from MemoryModel."); "MemoryServices only support classes that inherit from Model.");
} }
} }
_makeJson(int index, MemoryModel t) { _makeJson(int index, Model t) {
return t..id = index; return t..id = index.toString();
} }
Future<List> index([Map params]) async { Future<List> index([Map params]) async {
@ -47,7 +47,7 @@ class MemoryService<T> extends Service {
Future read(id, [Map params]) async { Future read(id, [Map params]) async {
int desiredId = _getId(id); int desiredId = _getId(id);
if (items.containsKey(desiredId)) { if (items.containsKey(desiredId)) {
MemoryModel found = items[desiredId]; Model found = items[desiredId];
if (found != null) { if (found != null) {
return _makeJson(desiredId, found); return _makeJson(desiredId, found);
} else } else
@ -58,12 +58,12 @@ class MemoryService<T> extends Service {
Future create(data, [Map params]) async { Future create(data, [Map params]) async {
//try { //try {
MemoryModel created = (data is MemoryModel) Model created =
? data (data is Model) ? data : god.deserializeDatum(data, outputType: T);
: god.deserializeDatum(data, outputType: T);
created.id = items.length; int size = items.length;
items[created.id] = created; created.id = size.toString();
items[size] = created;
return created; return created;
/*} catch (e) { /*} catch (e) {
throw new AngelHttpException.BadRequest(message: 'Invalid data.'); throw new AngelHttpException.BadRequest(message: 'Invalid data.');
@ -111,7 +111,7 @@ class MemoryService<T> extends Service {
int desiredId = _getId(id); int desiredId = _getId(id);
if (items.containsKey(desiredId)) { if (items.containsKey(desiredId)) {
MemoryModel item = items[desiredId]; Model item = items[desiredId];
items[desiredId] = null; items[desiredId] = null;
return _makeJson(desiredId, item); return _makeJson(desiredId, item);
} else } else

View file

@ -275,7 +275,7 @@ class Angel extends AngelBase {
} }
try { try {
await sendRequest(request, req, res); await sendResponse(request, req, res);
} catch (e, st) { } catch (e, st) {
_fatalErrorStream _fatalErrorStream
.add(new AngelFatalError(request: request, error: e, stack: st)); .add(new AngelFatalError(request: request, error: e, stack: st));
@ -332,8 +332,14 @@ class Angel extends AngelBase {
// return await closureMirror.apply(args).reflectee; // return await closureMirror.apply(args).reflectee;
} }
/// Sends a response. /// Use [sendResponse] instead.
@deprecated
Future sendRequest( Future sendRequest(
HttpRequest request, RequestContext req, ResponseContext res) =>
sendResponse(request, req, res);
/// Sends a response.
Future sendResponse(
HttpRequest request, RequestContext req, ResponseContext res) async { HttpRequest request, RequestContext req, ResponseContext res) async {
_afterProcessed.add(request); _afterProcessed.add(request);

View file

@ -39,7 +39,7 @@ class Service extends Routable {
AngelBase app; AngelBase app;
/// Retrieves all resources. /// Retrieves all resources.
Future<List> index([Map params]) { Future index([Map params]) {
throw new AngelHttpException.methodNotAllowed(); throw new AngelHttpException.methodNotAllowed();
} }
@ -88,7 +88,10 @@ class Service extends Routable {
Middleware indexMiddleware = getAnnotation(this.index, Middleware); Middleware indexMiddleware = getAnnotation(this.index, Middleware);
get('/', (req, res) async { get('/', (req, res) async {
return await this.index(mergeMap([req.query, restProvider])); return await this.index(mergeMap([
{'query': req.query},
restProvider
]));
}, },
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
@ -97,8 +100,12 @@ class Service extends Routable {
Middleware createMiddleware = getAnnotation(this.create, Middleware); Middleware createMiddleware = getAnnotation(this.create, Middleware);
post( post(
'/', '/',
(req, res) async => (req, res) async => await this.create(
await this.create(req.body, mergeMap([req.query, restProvider])), req.body,
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll( ..addAll(
@ -108,8 +115,12 @@ class Service extends Routable {
get( get(
'/:id', '/:id',
(req, res) async => await this (req, res) async => await this.read(
.read(toId(req.params['id']), mergeMap([req.query, restProvider])), toId(req.params['id']),
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll((readMiddleware == null) ? [] : readMiddleware.handlers)); ..addAll((readMiddleware == null) ? [] : readMiddleware.handlers));
@ -117,8 +128,13 @@ class Service extends Routable {
Middleware modifyMiddleware = getAnnotation(this.modify, Middleware); Middleware modifyMiddleware = getAnnotation(this.modify, Middleware);
patch( patch(
'/:id', '/:id',
(req, res) async => await this.modify(toId(req.params['id']), req.body, (req, res) async => await this.modify(
mergeMap([req.query, restProvider])), toId(req.params['id']),
req.body,
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll( ..addAll(
@ -127,8 +143,13 @@ class Service extends Routable {
Middleware updateMiddleware = getAnnotation(this.update, Middleware); Middleware updateMiddleware = getAnnotation(this.update, Middleware);
post( post(
'/:id', '/:id',
(req, res) async => await this.update(toId(req.params['id']), req.body, (req, res) async => await this.update(
mergeMap([req.query, restProvider])), toId(req.params['id']),
req.body,
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll( ..addAll(
@ -138,7 +159,11 @@ class Service extends Routable {
delete( delete(
'/:id', '/:id',
(req, res) async => await this.remove( (req, res) async => await this.remove(
toId(req.params['id']), mergeMap([req.query, restProvider])), toId(req.params['id']),
mergeMap([
{'query': req.query},
restProvider
])),
middleware: [] middleware: []
..addAll(handlers) ..addAll(handlers)
..addAll( ..addAll(

View file

@ -2,7 +2,7 @@ library angel_framework.test.common;
import 'package:angel_framework/angel_framework.dart'; import 'package:angel_framework/angel_framework.dart';
class Todo extends MemoryModel { class Todo extends Model {
String text; String text;
String over; String over;

View file

@ -4,7 +4,7 @@ import 'package:http/http.dart' as http;
import 'package:json_god/json_god.dart' as god; import 'package:json_god/json_god.dart' as god;
import 'package:test/test.dart'; import 'package:test/test.dart';
class Todo extends MemoryModel { class Todo extends Model {
String text; String text;
String over; String over;
} }