From d3d8f499821c3d4f363ee6905f64f0fc5c10d434 Mon Sep 17 00:00:00 2001 From: Chima Precious Date: Thu, 21 Dec 2023 11:56:26 +0000 Subject: [PATCH] inject request and response into controller --- yaroo/lib/http/http.dart | 49 ++++++++++++++++++------- yaroo/lib/src/_reflector/reflector.dart | 7 ++-- yaroo/lib/src/_router/definition.dart | 47 ++++++++++++------------ yaroo/lib/src/core.dart | 24 ++++++++++-- yaroo/test/router_test.dart | 2 +- 5 files changed, 83 insertions(+), 46 deletions(-) diff --git a/yaroo/lib/http/http.dart b/yaroo/lib/http/http.dart index b005d54d..807fbfc1 100644 --- a/yaroo/lib/http/http.dart +++ b/yaroo/lib/http/http.dart @@ -2,10 +2,11 @@ import 'dart:async'; -import 'package:meta/meta_meta.dart'; import 'package:yaroo/src/_reflector/reflector.dart'; import 'package:yaroo/src/core.dart'; +import 'http.dart'; + export 'package:pharaoh/pharaoh.dart' show Request, @@ -20,23 +21,43 @@ export 'package:pharaoh/pharaoh.dart' useShelfMiddleware; @inject -abstract class BaseController extends AppInstance {} +abstract class ApplicationController extends AppInstance { + late final Request request; -@inject -abstract class ServiceProvider extends AppInstance { - static List get defaultProviders => [AppServiceProvider]; + late final Response response; - FutureOr boot(); -} + Map get params => request.params; + + Map get query => request.query; + + Map get headers => request.headers; -@Target({TargetKind.parameter}) -class Param { - const Param(String name); + get body => request.body; + + Response badRequest([String? message]) { + const status = 422; + if (message == null) return response.status(status); + return response.json({'message': message}, statusCode: status); + } + + Response notFound([String? message]) { + const status = 404; + if (message == null) return response.status(status); + return response.json({'message': message}, statusCode: status); + } + + Response jsonResponse(data, {int statusCode = 200}) { + return response.json(data, statusCode: statusCode); + } + + Response redirectTo(String url, {int statusCode = 302}) { + return response.redirect(url, statusCode); + } } -@Target({TargetKind.parameter}) -class Body { - final String? param; +@inject +abstract class ServiceProvider extends AppInstance { + static List get defaultProviders => [AppServiceProvider]; - const Body({this.param}); + FutureOr boot(); } diff --git a/yaroo/lib/src/_reflector/reflector.dart b/yaroo/lib/src/_reflector/reflector.dart index 1bef1df4..803da1d2 100644 --- a/yaroo/lib/src/_reflector/reflector.dart +++ b/yaroo/lib/src/_reflector/reflector.dart @@ -64,7 +64,7 @@ ControllerMethod parseControllerMethod(ControllerMethodDefinition defn) { final method = defn.$2; final ctrlMirror = inject.reflectType(type) as r.ClassMirror; - if (ctrlMirror.superclass?.reflectedType != BaseController) { + if (ctrlMirror.superclass?.reflectedType != ApplicationController) { throw ArgumentError('$type must extend BaseController'); } @@ -74,8 +74,9 @@ ControllerMethod parseControllerMethod(ControllerMethodDefinition defn) { throw ArgumentError('$type does not have method #${symbolToString(method)}'); } - // final parameters = actualMethod.parameters.map((e) => e.reflectedType); - // print(parameters); + if (actualMethod.parameters.isNotEmpty) { + throw ArgumentError.value('$type.${actualMethod.simpleName}', null, 'Controller methods cannot have parameters'); + } return ControllerMethod(defn); } diff --git a/yaroo/lib/src/_router/definition.dart b/yaroo/lib/src/_router/definition.dart index 0b17c6e3..3e0ed4d5 100644 --- a/yaroo/lib/src/_router/definition.dart +++ b/yaroo/lib/src/_router/definition.dart @@ -1,8 +1,8 @@ import 'package:meta/meta.dart'; import 'package:pharaoh/pharaoh.dart'; -import '../../../http/http.dart'; import '../_reflector/reflector.dart'; +import '../core.dart'; import 'utils.dart'; enum RouteDefinitionType { route, group, middleware } @@ -46,10 +46,27 @@ class _MiddlewareDefinition extends RouteDefinition { typedef ControllerMethodDefinition = (Type controller, Symbol symbol); class ControllerMethod { - final ControllerMethodDefinition classMethod; - final List parameters = []; + final ControllerMethodDefinition method; - ControllerMethod(this.classMethod); + String get methodName => symbolToString(method.$2); + + Type get controller => method.$1; + + ControllerMethod(this.method); +} + +class ControllerMethodParam { + final String name; + final Type type; + final bool required; + final List metadata; + + const ControllerMethodParam( + this.name, + this.type, { + this.metadata = const [], + this.required = true, + }); } class ControllerRouteMethodDefinition extends RouteDefinition { @@ -63,12 +80,9 @@ class ControllerRouteMethodDefinition extends RouteDefinition { @override void commit(Spanner spanner) { + final handler = ApplicationFactory.buildControllerMethod(method); for (final routeMethod in route.methods) { - spanner.addRoute( - routeMethod, - route.path, - useRequestHandler(_controllerHandler(method)), - ); + spanner.addRoute(routeMethod, route.path, useRequestHandler(handler)); } } } @@ -134,18 +148,3 @@ class FunctionalRouteDefinition extends RouteDefinition { spanner.addRoute(method, path, useRequestHandler(handler)); } } - -RequestHandler _controllerHandler(ControllerMethod method) { - final defn = method.classMethod; - - return (req, res) async { - final instance = createNewInstance(defn.$1); - final mirror = inject.reflect(instance); - - final result = await Future.sync( - () => mirror.invoke(symbolToString(defn.$2), [req, res]), - ); - - return result; - }; -} diff --git a/yaroo/lib/src/core.dart b/yaroo/lib/src/core.dart index 238561aa..f4c8706b 100644 --- a/yaroo/lib/src/core.dart +++ b/yaroo/lib/src/core.dart @@ -87,9 +87,7 @@ abstract class ApplicationFactory { List get globalMiddlewares => [bodyParser]; - Future bootstrap({ - bool start_server = true, - }) async { + Future bootstrap({bool listen = true}) async { if (dbConfig != null) { DB.init(dbConfig!); await DB.defaultDriver.connect(); @@ -97,7 +95,7 @@ abstract class ApplicationFactory { await _bootstrapComponents(appConfig); - if (start_server) await startServer(); + if (listen) await startServer(); } Future startServer() async { @@ -128,4 +126,22 @@ abstract class ApplicationFactory { final application = (instanceFromRegistry() as _YarooAppImpl); return request(application._createPharaohInstance()); } + + static RequestHandler buildControllerMethod(ControllerMethod method) { + return (req, res) async { + final methodName = method.methodName; + final instance = createNewInstance(method.controller); + final mirror = inject.reflect(instance); + + mirror + ..invokeSetter('request', req) + ..invokeSetter('response', res); + + methodCall() => mirror.invoke(methodName, []); + + final result = await Future.sync(methodCall); + + return result; + }; + } } diff --git a/yaroo/test/router_test.dart b/yaroo/test/router_test.dart index bcdfb134..decc7a60 100644 --- a/yaroo/test/router_test.dart +++ b/yaroo/test/router_test.dart @@ -4,7 +4,7 @@ import 'package:yaroo/yaroo.dart'; import './router_test.reflectable.dart'; -class TestController extends BaseController { +class TestController extends ApplicationController { void create() {} void index() {}