dartist / express

A thin express-js inspired layer around Dart's primitive HttpServer APIs
Other
126 stars 11 forks source link

Multiple callbacks in route #16

Closed SamVerschueren closed 10 years ago

SamVerschueren commented 10 years ago

In Express it is possible to add multiple callbacks to a route, this is nice because you can add preconditions easily before the request is handled by a controller (for instance check if a user is signed in).

app.get('/dashboard', middleware.isSignedIn, dashboard.index);

It would be nice to have the same functionality in this library. I'm willing to take a look towards the possibilities.

mythz commented 10 years ago

Sure we'd take a pull request for something like this.

SamVerschueren commented 10 years ago

Oké thanks. Is the goal of the project to copy all the express features and method names (in order for Node devs to get them quickly going) or isn't it that strict? Would be cool though...

mythz commented 10 years ago

Nah doesn't have to be an exact match, if there's idioms that would make more sense for Dart we should use those instead. i.e. its not normal in Dart to have method overloading of positional arguments, as named params should be preferred or maybe we can extend HttpContext to look something like:

app.get('/dashboard', (HttpContext ctx) {
    ctx.use(middleware.isSignedIn)
      ..use(dashboard.index);
});
SamVerschueren commented 10 years ago

I thought that Dart had support for variable arguments but they don't so we have to do it differently, something like you posted. Although I don't find that a proper solution. When I build Node apps, I always create a Router class. In Dart I do it like this

import '../controllers/HomeController.dart';

class Router {

    HomeController home;

    Router() {
        home = new HomeController();
    }

    void register(Express app) {
        app.get('/', home.index);
        app.post('/contact', home.contact);
    }
}

By using your method it would become something like this if you want middleware.

import '../middleware/MyMiddleware.dart';
import '../controllers/HomeController.dart';

class Router {

    MyMiddleware middleware;
    HomeController home;

    Router() {
        middleware = new MyMiddleware();
        home = new HomeController();
    }

    void register(Express app) {
        app.get('/', (ctx) {
            ctx.use(middleware.isSignedIn)
                ..use(home.index);
        });
        app.post('/contact', home.contact);
    }
}

Maybe it's cleaner to do it like this

import '../middleware/MyMiddleware.dart';
import '../controllers/HomeController.dart';

class Router {

    MyMiddleware middleware;
    HomeController home;

    Router() {
        middleware = new MyMiddleware();
        home = new HomeController();
    }

    void register(Express app) {
        app.get('/').then(middleware.isSignedIn).then(home.index);
        app.post('/contact', home.contact);
    }
}

And working with the same next parameter as in NodeJS.

class MyMiddleware {
   void isSignedIn(HttpContext ctx, Function next) {
       // Check if the user is signed in

       next();
   }
}

Or another proper solution could be

class MyMiddleware {
   bool isSignedIn(HttpContext ctx) {
       // Check if the user is signed in

       return true;
   }
}

If the middleware returns true, continue to the next handler, otherwise it will stop? Maybe the latest with the boolean is the cleanest.

Let me know what you guys think of it.

SamVerschueren commented 10 years ago

Implemented it in https://github.com/SamVerschueren/express/tree/iss16. Can you guys have a look and give feedback.

Have to add documentation. But will wait for feedback and adjust things if necessary.