
Security News
Meet Socket at Black Hat Europe and BSides London 2025
Socket is heading to London! Stop by our booth or schedule a meeting to see what we've been working on.
route-decorator
Advanced tools
This library provides a decorator for mapping URL paths and queries to class methods. It's been designed with Typescript compatibility in mind but can be used in vanilla javascript if your environment or build tools support ES Decorators.
This module uses the path-to-regexp package to parse and match path strings. Take a look at that package's documentation to find out more about the syntax.
For query parameters, a simpler format is used - see down the page for more info.
You can install this package into your project from NPM using your favourite package manager.
For example, to install it using NPM's CLI tool, run npm install route-decorator.
This package exports its code as ES2022 JavaScript, and uses recent features like private fields, nullish coalescing assignment operator, and the ES module format.
If your environment doesn't support these features you will need to transpile this package before you use it.
Here is an example of usage:
import RouteMap from "route-decorator";
// Create an instance of the decorator
// Make sure you tell it the the shape of the class you're applying it to
// This is for type checking, so it's not important if you're using vanilla JS
const route = new RouteMap<Routes>;
// Apply the routes
class Routes {
// This is a plain route with no variables
@route('/')
home(){
// You can return anything from your route;
// A model, a controller, or a view for example
// It could be sync or async, or even an iterator
// Here we return just a string
//
// You could also refer to public or private fields set in the constructor.
return 'Home page'
}
// This is a route with a variable in the path.
// You must make sure the variable name in the path matches the variable name in the object
@route('/posts/:postId')
post({ postId }: { postId: string }) {
return 'Post ID ' + postId;
}
// This route has multiple URLs, and an optional variable with a default value
@route('/user/:userId')
@route('/default-user')
user({ userId }: { userId: string } = { userId: 'default-id' }) {
return 'User ID ' + userId
}
}
// You can now use the `route` object to generarte URLs based on your route method's function name:
route.compile('home') // returns '/'
route.compile('post', { postId: '1' }) // returns '/posts/1'
// The compile function will select the best route based on the arguments provided
route.compile('user', { userId: '2' }) // returns '/user/2'
route.compile('user') // returns '/default-user'
// If you're not sure whether the router has the route you want, use `compileOrNull`
route.compileOrNull('nope') // returns null
// To call your route function, you'll need an instance of your routes class:
const router = route.getRouter(new Routes);
// Check if a route exists:
router.has('/')
// Find multiple matching routes
for(const val of router.routeAll('/')) {
if(val !== null) {
console.log(val);
break;
}
}
// Find a specific route
router.route('/posts/100') // Throws an error if the route doesn't exist
router.routeOrNull('/user/fred') // Returns null if the route doesn't exist
You can match query parameters by passing in a second argument:
class Routes {
@route('/home', 'page=:page?&tag=:tags*&:rest...')
home({ page, tags, rest }: { page?: string, tags?: string[], rest: [string, string][] }) {
console.log(page, tags, rest);
}
@route('/', 'prev=true&page=:page')
preview(args) {
console.log(args)
}
}
const router = route.getRouter(new Routes());
router.route('/home', 'tag=red&page=4&tag=yellow&campaign=spring');
// logs '4' and ['red', 'yellow'] and [['campaign', 'spring']]
router.route('/', 'prev=true&page=1');
// logs { page: '1' }
route.compile('home', { page: '7', rest: [['newLayout', 'enabled']] })
// '/home?page=7&newLayout=enabled
route.compile('preview', { page: '2' })
// '/?prev=true&page=2
This matches parameters regardless of what order they appear.
The syntax for matching is different from URL matching:
param=:value matches a required single parameter called param into a value called valueparam=:value? matches an optional single parameterparam=:value+ matches one or more parameters called param into an array called valueparam=:value* matches zero or more:rest... matches any remaining unmatched parameters and stores them in an array of param-value tuples called restparam=example matches only if param=example is in the query object, but doesn't parse it to a valueYou currently can't use regular expressions
Here's an example of extending an existing router:
// Set up your basic router as above
const route = new RouteMap<Routes>();
class Routes {
@route('/')
home(){ return 'Home' }
}
// Create a new decorator/route map, cloning the existing one
const authRoute = new RouteMap<RoutesWithAuth>(route);
// Apply to your extended route class
class RoutesWithAuth extends Routes {
@authRoute('/auth')
auth() { return 'Auth endpoint'; }
}
// Continue as normal
const router = authRoute.getRouter(new RoutesWithAuth);
FAQs
A decorator for maping URL paths to class methods
We found that route-decorator demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket is heading to London! Stop by our booth or schedule a meeting to see what we've been working on.

Security News
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.