suresh
suresh

Reputation: 1013

Pattern match in nodejs rest url

In my node app I am using the router.use to do the token validation. I want to skip validation for few urls, so I want to check if the url matches, then call next();

But the URL I want to skip has a URLparam

E.g., this is the URL /service/:appname/getall. This has to be matched against /service/blah/getall and give a true.

How can this be achieved without splitting the url by '/'

Thanks in advance.

Upvotes: 3

Views: 1435

Answers (1)

Tristan
Tristan

Reputation: 56

The parameters will match :[^/]+ because it is a : followed by anything other than a / 1 or more times.

If you find the parameters in the template and replace them with a regex that will match any string you can do what you asked for.

let template = '/service/:appname/getall'
let url = '/service/blah/getall'

// find params and replace them with regex
template = template.replace(/:[^/]+/g, '([^/]+)')

// the template is now a regex string '/service/[^/]+/getall'
// which is essentially '/service/ ANYTHING THAT'S NOT A '/' /getall'

// convert to regex and only match from start to end
template = new RegExp(`^${template}$`)

// ^ = beggin
// $ = end
// the template is now /^\/service\/([^\/]+)\/getall$/

matches = url.match(template)
// matches will be null is there is no match.

console.log(matches)
// ["/service/blah/getall", "blah"]
// it will be [full_match, param1, param2...]

Edit: use \w instead of [^/], because:

The name of route parameters must be made up of “word characters” ([A-Za-z0-9_]). https://expressjs.com/en/guide/routing.html#route-parameters

I believe this is true for most parsers so I have updated my answer. The following test data will only work with this updated method.

let template = '/service/:app-:version/get/:amt';
let url = '/service/blah-v1.0.0/get/all';

template = template.replace(/:\w+/g, `([^/]+)` );

template = new RegExp(`^${template}$`);
let matches = url.match(template);

console.log(url);
console.log(template);
console.log(matches);
// Array(4) ["/service/blah-v1.0.0/get/all", "blah", "v1.0.0", "all"]

Upvotes: 4

Related Questions