-
Notifications
You must be signed in to change notification settings - Fork 223
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
Allow to chain event handlers #192
Comments
Hi @tobiasdiez. As explained in the relevant issue, h3 utilities like cors, are meant to be called functions on demand and in the body of the event handler as best practices. Middleware style chaining is also possible using an app stack, For the purpose of pre/post handlers, we might improve defineHandler BTW probably by supporting something like this: defineHandler((event) => {}, { before: [cors], after: [validate] }) Wdyt? |
Thanks for your answer!
That works, except if you want to chain two event handlers that you don't really have control (in my case the cors handler, and a apollo-h3-server handler that I'm currently developing). It is also not so convenient if the cors handler sometimes should handle the complete request (preflight) but in other cases only modify the response.
Nice suggestion. Is this production ready or is the overhead of
Sounds like a good idea. I guess if you need multiple handlers you just add them to the array? defineHandler((event) => {}, { before: [cors, auth], after: [validate] }) |
createApp is not working. ERROR: Invalid lazy handler result. It should be a function |
import { createApp } from "h3"
export default function eventHandlers(...handlers: Array<any>) {
const app = createApp()
app.use(handlers.map((func) => defineEventHandler(func)))
return app
} ERROR: [nuxt] [request error] [unhandled] [500] Invalid lazy handler result. It should be a function: |
@pi0 ? |
@notshekhar Currently the code for supporting lazy handlers is plaguing the interpretation of functions The correct way would be something like handlers.reduce((a, h) => a.use(eventHandler(h)), app); |
@nopeless I tried this and it worked handlers.reduce((a, h) => a.use(eventHandler(h)), app).handler |
Without the .handler it doesn't work? |
@nopeless No it wasn't working without .handler |
Oh, right, you were using nuxt. Yeah that should be the behaviour. I really think Nuxt should accept Router and App as well Thanks for responding quickly |
Found a solution that works here: #127 |
You can also try this I am using in my project, This function creates an event handler that executes all of the event handlers passed to it in the order they are received. The function returns the result of the first event handler that returns a value that is not undefined. If all of the event handlers return undefined, the function returns undefined as well. The event handler is asynchronous and awaits the result of each event handler before moving on to the next one. The event handler is also wrapped in another event handler called eventHandler. function eventHandlers(...handlers: Array<Function>) {
return eventHandler(async function chained(event: any) {
let res = undefined;
for (const func of handlers) {
res = await func(event);
if (res !== undefined) return res;
}
return res;
});
} |
Hi. Sorry for not adding comments on this for long time. I belive this is something worth to support to allow hooks such as authentication, cors and validation to run before and after event handler but chaining them is probably not best solution. Instead we are gonna support an object syntax for event handlers with |
Is the before/after syntax only a different syntax or will it behave differently? That is, are the following equivalent? defineEventHandler({ handler: d, before: [a,b,c], after: [e,f] })
chainEventHandlers([a,b,c,d,e,f]) If they are functionality-wise equivalent, then I'm indeed a fan of the before/after syntax as the ofther handlers are most likely defined globally somewhere else and only imported, and in this case this syntax is shorter and puts the focus on the actual event handler. |
It would be nice if event handlers could be chained to create a new event handler that invokes each handler after each other. Something like:
This is especially relevant for usage in nuxt, where one usually declares one event handler for a certain route and then in the declaration would like to specify cors options (using h3-cors) in parallel to invoking the actual handler.
Related: #177
The text was updated successfully, but these errors were encountered: