nitro icon indicating copy to clipboard operation
nitro copied to clipboard

Add option to skip middleware

Open Mokkapps opened this issue 1 year ago • 4 comments

Describe the feature

Hi, first thanks for this amazing project 💪🏻

In our Nuxt 3 app we have a core logic that heavily relies on Nitro's server middleware. For every server route we need to check if we want to render it in Nuxt or proxy the page from another system.

A simplified example:

export default defineEventHandler((event) => {
  if (event.path.startsWith('/skip')) {
    // middleware should not run for certain paths
    return;
  }

  if (event.path === '/cart') {
    console.log('First middleware redirect to cart');
    event.node.res.writeHead(302, {
      location: '/cart-redirect',
    });
    event.node.res.end();
  }

  if (event.path === '/user') {
    console.log('First middleware redirect to user');
    event.node.res.writeHead(302, {
      location: '/user-redirect',
    });
    event.node.res.end();
  }
});

As mentioned in the docs returning anything from middleware should be avoided:

Returning anything from a middleware will close the request and should be avoided! Any returned value from middleware will be the response and further code will not be executed however this is not recommended to do!

I'm wondering why Nitro does not provide something like a next() function to be able to skip certain middleware, as it is available in other frameworks like Express.

We definitely would like to avoid using an approach that is not recommended, what alternative would be available instead using server middleware with return for our requirements?

Reproduction

https://stackblitz.com/edit/github-yplgh6?file=server%2Fmiddleware%2F01.first.ts

Additional information

  • [x] Would you be willing to help implement this feature?

Mokkapps avatar Mar 08 '24 05:03 Mokkapps

I'm wondering why Nitro does not provide something like a next() function to be able to skip certain middleware, as it is available in other frameworks like Express.

You can return as you in the example. This should skip the middleware and is, AFAIK, the way to go.

Also sending redirects via middleware seems logical to me, here I wouldn't rely on the node primitives though and use sendRedirect instead.


If I am not mistaken here, this is probably something that should be better documented.

TheAlexLichter avatar Mar 08 '24 09:03 TheAlexLichter

I'm wondering why Nitro does not provide something like a next() function to be able to skip certain middleware, as it is available in other frameworks like Express.

You can return as you in the example. This should skip the middleware and is, AFAIK, the way to go.

Also sending redirects via middleware seems logical to me, here I wouldn't rely on the node primitives though and use sendRedirect instead.

If I am not mistaken here, this is probably something that should be better documented.

Thanks Alexander!

If this is the case, then we should definitely update the docs for Nitro & Nuxt as both mention that such returns should be avoided.

Mokkapps avatar Mar 08 '24 09:03 Mokkapps

Double checked with the team - redirects, throwing errors or skipping middleware are valid cases to "return". Cases like sending back data/HTML or a proxy are not 👀

Definitely something the docs should cover!

TheAlexLichter avatar Mar 08 '24 10:03 TheAlexLichter

Thanks for the update! I can try to update the documentation accordingly.

Actually, we're also returning HTML in our server middleware in certain scenarios 🙈 What would be the recommended workaround?

Mokkapps avatar Mar 08 '24 10:03 Mokkapps

we've been working with nuxt3 as well with the need of running some middlewares in some API paths, and not in others. In order to do that we've created a wrapper for defineEventHandler where we create conditionally run middlewares.

we've just publish this npm package that gives might help you with these cases:

https://www.npmjs.com/package/nitro-conditional-middleware

tmsf avatar Nov 01 '24 15:11 tmsf