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

Add support for route middleware #87

Closed
mjdickinson opened this issue Dec 19, 2018 · 12 comments
Closed

Add support for route middleware #87

mjdickinson opened this issue Dec 19, 2018 · 12 comments
Milestone

Comments

@mjdickinson
Copy link

Allow middleware to be added per route in order to support this style of route declaration:

api.post(
	'/user',
	authenticate(),
	authorize({ role: 'admin' },
	validate({
		body: { /*...schema...*/ }
	})
	async (req, res) => {
		/*
		   business logic
		*/
		return {}
	}
)

...where authenticate, authorize and validate are middleware (factory) functions.

@jeremydaly
Copy link
Owner

This is completely possible. Just to confirm the format:

api.post(
  '/user',
  authenticate(),
  authorize({ role: 'admin' }),
  validate({ body: { /*...schema...*/ } }),
  async (req, res) => {
    /* business logic */
    return {}
  }
)

What would the signature be of these factory functions? Middleware in Lambda API requires the acceptance of three parameters, REQUEST, RESPONSE and next(). Would you expect authorize({ role: 'admin' }) to return a function with that signature so that it could be processed like normal middleware? Or are you envisioning something else?

@nickmeldrum
Copy link

I was just about to add a similar request because I wanted some of my middleware to only operate on a particular method as well as endpoint.

I was thinking that the post() and get() methods etc. could allow a next() method passed in, which is I think possible in express?

However it looks like this request would also satisfy my request?

@nickmeldrum
Copy link

and my 2cents would be exactly as you describe - I would expect my middleware function to have to have the same signature whether I include it like the OP suggested or if I include it using the api.use() method.

@jeremydaly
Copy link
Owner

Not sure we would want to allow next() to be passed into route methods, but if route specific middleware uses the same signature as use(), then it's entirely possible to read the last parameter as the handler and then any proceeding functions as middleware. The middleware would be passed the REQUEST, RESPONSE and next() parameters and would control the execution flow just like normal middleware.

If that is how it is envisioned, then it should be fairly simple to implement.

@mjdickinson
Copy link
Author

mjdickinson commented Dec 20, 2018 via email

@jeremydaly
Copy link
Owner

We could move middleware processing into the route, but mappings are all preprocessed anyway. So, it might be better to add method filtering to middleware, and then just map it correctly when processing route declarations. That way middleware processing doesn't need to change AND you get the benefit of adding use to restrict methods if you wanted to do it that way.

I'm thinking this is just a convenience method, and really doesn't change the underlying processing too much.

@mjdickinson
Copy link
Author

mjdickinson commented Dec 20, 2018 via email

@jeremydaly
Copy link
Owner

Hmm, I see what you mean. Could be useful to use the nested routes tree to store middleware mappings. I'd need to think about how that would work for global middleware though as we'd have to handle wildcard routes too. I wouldn't want global middleware to be tied to each route though, seems as though we could do that higher up the tree.

@mjdickinson
Copy link
Author

mjdickinson commented Dec 20, 2018 via email

@jeremydaly jeremydaly added this to the v0.10 milestone Dec 26, 2018
@jeremydaly
Copy link
Owner

I'm thinking about changing the entire execution stack so that even the 'handler route' is just like another piece of middleware, similar to how Express creates their middleware stacks. They essentially have the same signatures (minus the next()), so it might be more efficient to build the stack when it parses the request, and then just iterate through all the middlewares.

Need to think about maintaining processing order though, especially for wildcard and other global routes.

@jeremydaly
Copy link
Owner

  • Double check route matching based on method. Should be returning a "Method not allowed" if the route exists.

@mjdickinson
Copy link
Author

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants