MatthiasKunnen / nest-fastify-middleware-hooks-demo

Nest middleware demo for Fastify using hooks instead of middie

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

NestJs fastify middleware: Problems and solutions

Reported here nestjs/nest#11585.

Install instructions

Running this demo:

  1. yarn install
  2. yarn run start
  3. Open / in a browser. This page shows the results of fetching every route for the configured adapter.

Fastify results

Fastify results

Result for FastifyAdapter as shown when visiting `/`.

Repo scenario

The scenario in this repo is as follows:

SubRouteController (middleware applied)
├── /subroute
└── /subroute/yes

SubRouteNoController
└── /subroute/no

SimilarRoutesController (middleware applied)
├── /similar/test
└── /similar/:id

AbcController (middleware applied)
├── /a
├── /a/b
└── /a/b/c

TestResultsController
└── / (Shows the result of every route)

Test results for all adapters

Path Expected Express Fastify CustomFastify
/subroute 1 1 1 1
/subroute/no 0 0 1 0
/subroute/yes 1 1 2 1
/similar/test 1 2 2 1
/similar/123 1 1 1 1
/a 1 1 1 1
/a/b 1 1 2 1
/a/b/c 1 1 3 1

Problems in the existing fastify-adapter

Middleware is executed on subroutes

Registering middleware on a controller that has a / route, will lead to that middleware executing on all routes regardless of controller. This affects all subroutes of a route with middleware.

This is not a problem using the express adapter.

Test this

  1. Go to /subroute/no or view the results on /
  2. (optional) Use the express adapter in main.ts, the middleware will not be executed

See subroute.controller.ts and subroute-no.controller.ts

Middleware is executed multiple times for the same route

If a controller that has middleware applied has n routes that are prefixes of each other, the middleware will be called n times for the most specific URL. It should only be called once.

Test this

Given the following routes: /a, /a/b, and /a/b/c, requesting /a/b/c results in

{"message":"Middleware executed","fullUrl":"/a/b/c","requestUrl":"/b/c"}
{"message":"Middleware executed","fullUrl":"/a/b/c","requestUrl":"/c"}
{"message":"Middleware executed","fullUrl":"/a/b/c","requestUrl":"/"}

See src/abc.controller.ts.

The cause

This behavior is intended for middie which is used by fastify. Instead, hooks should be used. See this issue: fastify/middie#113.

References:

A proposed solution

I have created a modified CustomFastifyAdapter to use hooks instead of middie, this solves both problems. This adapter can be tested by editing main.ts.

Middie could be made entirely optional though it might still be required for express middleware.

About

Nest middleware demo for Fastify using hooks instead of middie


Languages

Language:TypeScript 100.0%