Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fastify middleware - access to query and params?

trying to get middleware working in Fastify - I don't seem to have access to the query or params. The docs say:

Fastify supports out of the box Express/Restify/Connect middlewares, this means that you can just drop-in your old code and it will work! (faster, by the way)

But with a simple example:

fastify.use(function(req, res, next) {
  console.log('req.query', req.query);   // undefined
  console.log('req.params', req.params); // undefined
  next();
});

Same if I add/restrict the url:

fastify.use('/foo', function(req, res, next) {

I'm sure I am missing something, but the docs do claim it 'just works' - which I can't see how if you don't get access to the qs?

[I think I can re-write to use hooks, but I'm really interested in how I am meant to be doing this with middleware]

Thanks

like image 560
Calv J Avatar asked Mar 03 '23 12:03

Calv J


2 Answers

This was answered when Fastify 2 was the main version. This answer may not be correct for Fastify 3


While Fastify is compatible with Express/Restify method signature, it isn't exactly the same values being passed in. The method signature is:

/**
 * Generic middleware method
 * @param {http.IncomingMessage} req
 * @param {http.ServerResponse} res
*/
const middleware = (req, res) => {
}

fastify.use(middleware)

When using .use, Fastify only deals with the Node.js HTTP classes which do not provide the .params or .query fields.

Express adds these fields as a nicety to developers. If the middleware you use relies on those features, unfortunately, it will not be a direct drop in.

All is not lost

If you choose to migrate your middleware to Fastify, the .params and .query fields are available on the Request object.

Using the middleware in your question, this is what the Fastify version would look like.

fastify.addHook('onRequest', function(request, reply, done) {
  console.log('query', request.query);
  console.log('params', request.params);

  done();
})

Fastify is asking developers to think more in terms of Hooks and less in terms of Middleware. This provides more flexibility and greater speed but can be a little more complicated to write at times.

Additional reading

The Lifecycle and Hooks documentation on the Fastify site give more detail on how these pieces work together.

The Middleware documentation provides more detail on what features are supported.

Somewhat related, using Plugins you are able to scope to a particular path.

References

Express middleware support

From the Middleware documentation:

Furthermore, methods added by Express and Restify to the enhanced versions of req and res are not supported in Fastify middlewares.

and

Express modifies the prototype of the node core Request and Response objects heavily so Fastify cannot guarantee full middleware compatibility.

Express adding .params and .query

Express adding .query to request and where Express runs the query middleware

Express adding parameters to route.

like image 84
mattcan Avatar answered Mar 11 '23 02:03

mattcan


The .use() function is only a utility to help users to migrate from Express to Fastify. The input function interface is (req, res, next) but the req and res object are the standard Node.js objects http.ClientRequest and http.ServerResponse (that is the same interface of Express middleware). So the assumption is that the users have implemented middleware for Express using the standard Node.js's objects.

To archive your needs you should parse the req.url as described here. The .use API will be deprecated in Fastify v3.

Instead, if you want to start developing with Fastify you should migrate to .register. The register is the great feature of Fastify that offer encapsulation

like image 37
Manuel Spigolon Avatar answered Mar 11 '23 04:03

Manuel Spigolon