4

I need an equivalent of following express.js code in simple node.js that I can use in middleware. I need to place some checks depending on the url and want to do it in a custom middleware.

app.get "/api/users/:username", (req,res) ->
  req.params.username

I have the following code so far,

app.use (req,res,next)->
  if url.parse(req.url,true).pathname is '/api/users/:username' #this wont be true as in the link there will be a actual username not ":username" 
    #my custom check that I want to apply
AtaurRehman Asad
  • 173
  • 1
  • 1
  • 8

3 Answers3

5

A trick would be to use this:

app.all '/api/users/:username', (req, res, next) ->
  // your custom code here
  next();

// followed by any other routes with the same patterns
app.get '/api/users/:username', (req,res) ->
  ...

If you only want to match GET requests, use app.get instead of app.all.

Or, if you only want to use the middleware on certain specific routes, you can use this (in JS this time):

var mySpecialMiddleware = function(req, res, next) {
  // your check
  next();
};

app.get('/api/users/:username', mySpecialMiddleware, function(req, res) {
  ...
});

EDIT another solution:

var mySpecialRoute = new express.Route('', '/api/users/:username');

app.use(function(req, res, next) {
  if (mySpecialRoute.match(req.path)) {
    // request matches your special route pattern
  }
  next();
});

But I don't see how this beats using app.all() as 'middleware'.

robertklep
  • 198,204
  • 35
  • 394
  • 381
3

You can use node-js url-pattern module.

Make pattern:

var pattern = new UrlPattern('/stack/post(/:postId)');

Match pattern against url path:

pattern.match('/stack/post/22'); //{postId:'22'}
pattern.match('/stack/post/abc'); //{postId:'abc'}
pattern.match('/stack/post'); //{}
pattern.match('/stack/stack'); //null

For more information, see: https://www.npmjs.com/package/url-pattern

  • I want to find a pattern from URI as I've multiple pattern store in DB, I want to authorise each URL in a microservice gateway. – Ketav Jan 23 '20 at 10:23
2

Just use the request and response objects as you would in a route handler for middleware, except call next() if you actually want the request to continue in the middleware stack.

app.use(function(req, res, next) {
  if (req.path === '/path') {
    // pass the request to routes
    return next();
  }

  // you can redirect the request
  res.redirect('/other/page');

  // or change the route handler
  req.url = '/new/path';
  req.originalUrl // this stays the same even if URL is changed
});
hexacyanide
  • 88,222
  • 31
  • 159
  • 162
  • I need to match this pattern "/api/users/:username" and I can't do that with simple comparison. – AtaurRehman Asad Oct 01 '13 at 13:11
  • You can use `.split()` on `req.path` and check if `url[1] === 'api'`, `url[2] === 'users'`, etc. – hexacyanide Oct 01 '13 at 13:16
  • 1
    Yes I can do that. I'm just wondering if there is some standard way of doing that. Any node library etc. Thanks for the help so far. – AtaurRehman Asad Oct 01 '13 at 13:20
  • There isn't really a standard way to match URLs, most would either used a regular expression or switch, is there is a reason why you want to put this routing into middleware rather than routes? – hexacyanide Oct 02 '13 at 02:04