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

learning: nitro middleware #81

Open
Drew-Macgibbon opened this issue Jul 2, 2023 · 2 comments
Open

learning: nitro middleware #81

Drew-Macgibbon opened this issue Jul 2, 2023 · 2 comments
Assignees
Labels
🗣️ discuss further discussion is required

Comments

@Drew-Macgibbon
Copy link
Contributor

This is a running thread of my findings about nitro middlewares.

@Drew-Macgibbon Drew-Macgibbon added the 🗣️ discuss further discussion is required label Jul 2, 2023
@Drew-Macgibbon Drew-Macgibbon self-assigned this Jul 2, 2023
@Drew-Macgibbon
Copy link
Contributor Author

I can log server event timings as middleware like this:

export default defineEventHandler((event) => {
  const { req, res } = event.node
  const startTime = Date.now()
  logger.info(`event start: ${req.url}`)
  res.on('finish', () => {
    const endTime = Date.now()
    logger.info(`Request finished: ${endTime - startTime}ms`)
  })
})

Middleware is run on every request, there's no way to add middleware to specific routes like with express.
Instead, you can check the request URL and run it then.

export default defineEventHandler((event) => {
  // Will only execute for /auth route
  if (getRequestURL(event).startsWith('/auth')) {
    event.context.user = { name: 'Nitro' }
  }
})

@Drew-Macgibbon
Copy link
Contributor Author

Drew-Macgibbon commented Jul 2, 2023

Findings:

  • middleware is executed in top-down order, order by priority with perfixes 1.first.ts | 2.second.ts do the same for folders 1.firstDir | 2.secondDir
  • middleware can modify the request before it is processed, not after.
  • returning anything from a middleware will close the request.

example of use restricting admin api routes:

export default defineEventHandler((event) => {
  logger.info('run auth check before other middleware')
  const { res } = event.node
  const isAdmin = false
  if (event.path.startsWith('/api/admin')) {
    if (!isAdmin) {
      logger.info('not an admin')
      // res.end('status: 403, message: You are not an admin')
      return { status: 403, body: 'You are not an admin' }
    }
    logger.info('you are an admin, continue with other middleware')
  }
})

you can use either return { } or res.end() to terminate the request.
return is preferable imo because it returns structured JSON to the screen.

sendRedirect(event, redirectPath, 302) can also be used instead of returning any data. Although for redirects I think it makes sense to do that on the client side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🗣️ discuss further discussion is required
Projects
None yet
Development

No branches or pull requests

1 participant