Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove app.router and refactor middleware processing #1909

Merged
merged 1 commit into from Feb 3, 2014

Conversation

defunctzombie
Copy link
Contributor

This is an overhaul of middleware processing, Router and Route. Connect is no
longer used to process the middleware stack. This functionality has been
split into two parts: middleware stack and default error response.

The entry point for request processing is the app.handle method. It
sets up the default error response handle (to run in the event of no
other error handler) and then triggers the app router (instance of
Router) to handle the request.

The app router handle function contains the middleware dispatch layer
previously in the connect codebase. This layer handle the logic for
dispatching .use calls (stripping paths if needed). The app contains a
base router app._router. New routes can be created and .used on this
router to organize routes into files.

Routers now have the following methods .use, .all, .param which
are all public.

Additionally, Routers have a .route(path) method which returns a new
instance of Route for the requested path. Route(s) are isolated
middleware stacks and contain methods for the HTTP verbs as well as an
.all method to act similar to middleware. These methods are chainable
to easily describe requirements for a route.

var route = Router.route('/foo'); // or 'app.route('/foo')'

route
.all(auth)
.get(function(...) {})
.all(more_checks)
.post(function(...) {})

Any Route and Router methods which accept handlers also accept error
(arity 4) handlers which will also behave as expected.

Finally, the app.router getter has been removed. Middleware and
handlers are run IN THE ORDER they are seen in the file. This means that
code which injected the app.router and then added error handlers (or
other middleware) will need to be updated to move those handlers after
any requests added on the app object. The examples have been updated
accordingly. This is the largest breaking change to codebases in this
commit.

@jonathanong jonathanong mentioned this pull request Jan 26, 2014
11 tasks
@defunctzombie
Copy link
Contributor Author

This is the actual cleaned up PR for the major routing overhaul. All of the tests and examples have been updated to reflect the new behavior. No new examples have been added yet nor have new expressjs.com docs been written for this. I do encourage those with existing express apps to clone this and see how your existing express app runs. Ideally it should just work as the majority of the changes were in private APIs. Using app.router will throw now and tell you to read the migration guide (to be created). But basically, all you need to do is move any middleware after the app.router insertion that are not routes to after the routes (like you would have expected from day 1).

return next_layer(err);
}

var arity = layer.handle.length;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dope

@defunctzombie
Copy link
Contributor Author

If there are objections please state them. This will hang around till about midweek and if no one objects, then this code will marry the master branch. If you have an objection but don't have time to say why yet, please just say that so you don't sit in silence :)

* @api public
*/

app.router = function(){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this even necessary? why would someone need this in 4.0?

maybe we can just make this a getter with a deprecation notice and return a noop as well as remove "docs" on it. it would make it more obvious that it's deprecated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was suppose to be a way to get the app's router (as it says). The thinking is that you should be able to access that object in the event there are methods on it we don't proxy via app... maybe that is all useless thinking.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i think tj had an issue for that. i'm not sure if it's necessary though. i just think it's bad if we use the same name for a property but use it completely differently. better to just have a completely different name. even a public ._router is okay to me as it tells me "it's internal so i shouldn't have to touch it, but it's there".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea it was just a legacy thing for mounting router in the desired spot, shouldn't be an issue if we're doing per-router-middleware

@jonathanong
Copy link
Member

can't see anything wrong right now. i'll look through again later.

@defunctzombie
Copy link
Contributor Author

I have updated the PR with changes from comments

  • removed app.router() function.
  • app.route getter throws message (I decided to throw because I favor fast failure versus silent death)
  • updated History

The decisions on app.use(another_app) are not made in the PR so things like app.mountpoint remain. The decision on whatever to allow app mounting or to remove that feature altogether will be made in a separate issue/PR.

@defunctzombie
Copy link
Contributor Author

Would love to get a LGTM on this or a no so I can move on to some of the other items :) This item is a blocker for fully removing the connect dependency.

@reqshark
Copy link
Contributor

+1

@hallas
Copy link

hallas commented Jan 31, 2014

👍 looks good to me :)

This is an overhaul of middleware processing, Router and Route. Connect is no
longer used to process the middleware stack. This functionality has been
split into two parts: middleware stack and default error response.

The entry point for request processing is the `app.handle` method. It
sets up the default error response handle (to run in the event of no
other error handler) and then triggers the app router (instance of
Router) to handle the request.

The app router `handle` function contains the middleware dispatch layer
previously in the connect codebase. This layer handle the logic for
dispatching `.use` calls (stripping paths if needed). The app contains a
base router `app._router`. New routes can be created and `.use`d on this
router to organize routes into files.

Routers now have the following methods `.use`, `.all`, `.param` which
are all public.

Additionally, Routers have a `.route(path)` method which returns a new
instance of Route for the requested path. Route(s) are isolated
middleware stacks and contain methods for the HTTP verbs as well as an
`.all` method to act similar to middleware. These methods are chainable
to easily describe requirements for a route.

  var route = Router.route('/foo'); // or 'app.route('/foo')'

  route
  .all(auth)
  .get(function(...) {})
  .all(more_checks)
  .post(function(...) {})

Any Route and Router methods which accept handlers also accept error
(arity 4) handlers which will also behave as expected.

Finally, the `app.router` getter has been removed. Middleware and
handlers are run IN THE ORDER they are seen in the file. This means that
code which injected the `app.router` and then added error handlers (or
other middleware) will need to be updated to move those handlers after
any requests added on the app object. The examples have been updated
accordingly. This is the largest breaking change to codebases in this
commit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants