Server
Middlewares

Utilizing Middlewares

Middlewares provide a way to handle requests prior to their processing by the router. They are essentially functions that execute before the request is handled and can be used for authentication, logging, and other similar tasks.

If a handler function doesn't return a Response object, the request will be passed onto the next handler.

Here's an example:

import { createRouter, Response } from 'fets'
 
const router = createRouter()
  // Log certain headers prior to the response
  .route({
    path: '*',
    handler: request => {
      console.log(`User Agent: ${request.headers.get('user-agent')}`)
    }
  })
  // Or halt the request early
  .route({
    path: '*',
    handler: request => {
      if (!request.headers.get('authorization')) {
        return new Response(null, {
          status: 401
        })
      }
    }
  })
  .route({
    path: '/users',
    method: 'GET',
    schemas: {
      /** .. */
    },
    handler: request => {
      // This code won't be reached if the request lacks an `Authorization` header.
    }
  })

Chaining Multiple Handlers

It's also possible to link multiple handlers to a single route. In the following example, we're verifying if the request includes an Authorization header and whether the user holds admin status.

import { createRouter, Response, RouteHandler } from 'fets'
 
const withAuth: RouteHandler = request => {
  if (!request.headers.get('Authorization')) {
    return new Response(null, {
      status: 401
    })
  }
}
 
const router = createRouter().route({
  path: '/users',
  method: 'GET',
  schemas: {
    /** .. */
  },
  handler: [
    withAuth,
    request => {
      // This code won't be reached if the request lacks an `Authorization` header.
    }
  ]
})

Using schemas as an Alternative to Middlewares (recommended)

You can validate the Authorization header directly using schemas as an alternative to middlewares:

import { createRouter, Response } from 'fets'
 
const router = createRouter().route({
  path: '/me',
  method: 'GET',
  schemas: {
    request: {
      headers: {
        authorization: {
          type: 'string',
          // We can use a regex to validate the `Authorization` header.
          pattern: /^Bearer .+$/
        },
        required: ['authorization']
      }
    },
    responses: {
      /** .. */
    },
    handler: request => {
      // This code won't be reached if the request doesn't have a valid Bearer token in the `Authorization` header.
    }
  } as const
})