{"id":19807617,"url":"https://github.com/notninja/routerify","last_synced_at":"2025-07-17T18:04:45.517Z","repository":{"id":57355686,"uuid":"76455467","full_name":"NotNinja/routerify","owner":"NotNinja","description":"Opinionated router loader for Express-like applications","archived":false,"fork":false,"pushed_at":"2017-05-15T23:37:14.000Z","size":58,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-11T07:36:01.267Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NotNinja.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-12-14T11:56:36.000Z","updated_at":"2017-05-15T22:30:44.000Z","dependencies_parsed_at":"2022-09-26T16:31:42.782Z","dependency_job_id":null,"html_url":"https://github.com/NotNinja/routerify","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNinja%2Frouterify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNinja%2Frouterify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNinja%2Frouterify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NotNinja%2Frouterify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NotNinja","download_url":"https://codeload.github.com/NotNinja/routerify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241150645,"owners_count":19918353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T09:11:27.234Z","updated_at":"2025-02-28T12:33:55.212Z","avatar_url":"https://github.com/NotNinja.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"    8888888b.                   888                    d8b  .d888\n    888   Y88b                  888                    Y8P d88P\"\n    888    888                  888                        888\n    888   d88P .d88b.  888  888 888888 .d88b.  888d888 888 888888 888  888\n    8888888P\" d88\"\"88b 888  888 888   d8P  Y8b 888P\"   888 888    888  888\n    888 T88b  888  888 888  888 888   88888888 888     888 888    888  888\n    888  T88b Y88..88P Y88b 888 Y88b. Y8b.     888     888 888    Y88b 888\n    888   T88b \"Y88P\"   \"Y88888  \"Y888 \"Y8888  888     888 888     \"Y88888\n                                                                       888\n                                                                  Y8b d88P\n                                                                   \"Y88P\"\n\n[Routerify](https://github.com/NotNinja/routerify) is an opinionated router loader for Express-like applications.\n\n[![Build](https://img.shields.io/travis/NotNinja/routerify/develop.svg?style=flat-square)](https://travis-ci.org/NotNinja/routerify)\n[![Coverage](https://img.shields.io/codecov/c/github/NotNinja/routerify/develop.svg?style=flat-square)](https://codecov.io/gh/NotNinja/routerify)\n[![Dependencies](https://img.shields.io/david/NotNinja/routerify.svg?style=flat-square)](https://david-dm.org/NotNinja/routerify)\n[![Dev Dependencies](https://img.shields.io/david/dev/NotNinja/routerify.svg?style=flat-square)](https://david-dm.org/NotNinja/routerify?type=dev)\n[![License](https://img.shields.io/npm/l/routerify.svg?style=flat-square)](https://github.com/NotNinja/routerify/blob/master/LICENSE.md)\n[![Release](https://img.shields.io/npm/v/routerify.svg?style=flat-square)](https://www.npmjs.com/package/routerify)\n\n* [Install](#install)\n* [Configurations](#configurations)\n* [API](#api)\n* [Bugs](#bugs)\n* [Contributors](#contributors)\n* [License](#license)\n\n## Install\n\n``` bash\n$ npm install --save routerify\n```\n\nYou'll need to have at least [Node.js](https://nodejs.org) 6 or newer.\n\n## Configurations\n\nRouterify is opinionated. Routerify is also configurable and extensible via plugins. The two core plugin types that\nRouterify has are *Registrars* and *Mounters*. Through these, Routerify can be configured to load routes from modules in\nany pattern and mount them onto any server.\n\n### Registrars\n\nRegistrars are responsible for picking which source files within the directory should be loaded as modules and how the\nroutes are extracted from the modules. These routes are then passed to the mounter.\n\nRouterify includes some opinionated registrars. If you don't like our opinion, you can either not use Routerify **or**\nyou can simply [create your own](#create-your-own-registrar) and, optionally,\n[create a pull request](https://github.com/NotNinja/routerify/compare) to share it with everyone, provided our opinions\nmatch :) If not, you can always release it as a plugin.\n\n#### `IndexRegistrar`\n\n**Name:** `\"index\"`  \n**Default:** Yes  \n**How it works:**\n\nIt expects the following file structure under the target directory:\n\n```\n- /\n  - users/\n    - _userId/\n      - sessions/\n        - index.js\n      - index.js\n    - helper.js\n    - index.js\n```\n\nOnly files whose base name is `index` will be loaded (e.g. `helper.js` in the above example would be ignored) and it\nexpects each one of those modules to export an object whose values are either a single handler method or an array of\nhandler methods. Only handlers associated with properties on the object whose name matches that of a supported verb will\nbe registered.\n\nIf we were to build on the example above and say that the `/users/index.js` file looked something like this:\n\n``` javascript\nmodule.exports = {\n  del(req, res, next) {\n    ...\n  }\n  get(req, res, next) {\n    ...\n  },\n  put(req, res, next) {\n    ...\n  },\n  fetchUser(userId) {\n    ...\n  }\n}\n```\n\nThen we could say that at least (we're ignoring routes defined in the other files for the purpose of this example) the\nfollowing routes would be registered:\n\n* `DELETE /users/:userId`\n* `GET /users/:userId`\n* `PUT /users/:userId`\n\nThe `fetchUser` method is ignored because it does not match a supported verb.\n\n#### `VerbRegistrar`\n\n**Name:** `\"verb\"`  \n**Default:** No  \n**How it works:**\n\nIt expects the following file structure under the target directory:\n\n```\n- /\n  - users/\n    - _userId/\n      - sessions/\n        - get.js\n      - del.js\n      - get.js\n      - put.js\n    - get.js\n    - helper.js\n    - post.js\n```\n\nOnly files whose base name matches that of a supported verb will be loaded (e.g. `helper.js` in the above example would\nbe ignored) and it expects each one of those modules to export either a single handler method or an array of handler\nmethods.\n\nIn the example above, the following routes would be registered:\n\n* `GET /users`\n* `POST /users`\n* `DELETE /users/:userId`\n* `GET /users/:userId`\n* `PUT /users/:userId`\n* `GET /users/:userId/sessions`\n\n#### Create your own Registrar\n\nIn order to create your own registrar you simply need to extend the `Registrar` class and tell Routerify about it:\n\n``` javascript\nconst routerify = require('routerify')\nconst Registrar = require('routerify/src/registrar')\n\nclass CustomRegistrar extends Registrar {\n\n  getPluginName() {\n    return 'custom'\n  }\n\n  register(file, options) {\n    // Load the module, extract the routes, and mount them via this.mounter\n    ...\n  }\n}\n\nrouterify.use(new CustomRegistrar())\n\nmodule.exports = CustomRegistrar\n```\n\nNow your new registrar can be used by simply specifying its name in the options:\n\n``` javascript\nrouterify({\n  dir: path.join(__dirname, 'routes'),\n  registrar: 'custom',\n  server: app\n})\n```\n\nYou probably want to take a look at the relevant\n[source code](https://github.com/NotNinja/routerify/tree/master/src/registrar) before trying to create your own\nregistrar.\n\n### Mounters\n\nMounters are primarily responsible for taking the routes and mounting them onto the server. However, they also provide\nthe default verbs (methods supported by the framework to make route requests for specific HTTP methods) when no `verbs`\noption is specified, and they determine how parameter path variables are formatted.\n\nRouterify includes some mounters for common server frameworks. If your favorite framework is not supported, you can\n[create your own](#create-your-own-mounter) and, optionally,\n[create a pull request](https://github.com/NotNinja/routerify/compare) to share it with everyone.\n\n#### `ExpressMounter`\n\n**Name:** `\"express\"`  \n**Default:** Yes  \n**Description:**\n\nSupports all [Express](http://expressjs.com)-like frameworks.\n\n#### `RestifyMounter`\n\n**Name:** `\"restify\"`  \n**Default:** No  \n**Description:**\n\nSupports the [Restify](http://restify.com) framework. Since Restify is an Express-like framework itself, the\n`ExpressMounter` will work well for the most part, however, this extension of `ExpressMounter` provides additional\nbenefits for Restify applications by allowing extra optional information (e.g. `version`/`versions`) to be used when\nmounting routes.\n\nThis can be done by simply adding an `options` property containing the additional information to one of the route\nhandlers and it will be passed in.\n\n#### Create your own Mounter\n\nIn order to create your own mounter you simply need to extend the `Mounter` class and tell Routerify about it:\n\n``` javascript\nconst routerify = require('routerify')\nconst Mounter = require('routerify/src/mounter')\n\nclass CustomMounter extends Mounter {\n\n  formatParamPath(param) {\n    // Format param for insertion into the route URL\n    return ...\n  }\n\n  getDefaultVerbs() {\n    // Specify the supported verbs\n    return [...]\n  }\n\n  getPluginName() {\n    return 'custom'\n  }\n\n  mount(url, verb, handlers, options) {\n    // Mount the route onto options.server\n    ...\n  }\n}\n\nrouterify.use(new CustomMounter())\n\nmodule.exports = CustomMounter\n```\n\nNow your new mounter can be used by simply specifying its name in the options:\n\n``` javascript\nrouterify({\n  dir: path.join(__dirname, 'routes'),\n  mounter: 'custom',\n  server: app\n})\n```\n\nYou probably want to take a look at the relevant\n[source code](https://github.com/NotNinja/routerify/tree/master/src/mounter) before trying to create your own mounter.\n\n## API\n\nRouterify exposes its API primarily through a single method.\n\n### `routerify(options)`\n\nThis is the primary method for Routerify and it will go through the target directory, find all routes using the\n[registrar](#registrars), and finally mounts them onto the server using the [mounter](#mounter).\n\n``` javascript\nconst express = require('express')\nconst path = require('path')\nconst routerify = require('routerify')\nconst app = express()\n\nrouterify({\n  dir: path.join(__dirname, 'routes'),\n  server: app\n})\n\napp.listen(3000, () =\u003e {\n  console.log('Example app listening on port 3000!')\n})\n```\n\n#### Options\n\nThe following options can be passed to Routerify:\n\n| Option         | Description                                                                                                                   | Default Value                |\n| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |\n| `dir`          | The directory containing the routes to be loaded.                                                                             | `process.cwd()`              |\n| `ext`          | The extension of the source files to be loaded.                                                                               | `\".js\"`                      |\n| `glob`         | Any options to be passed to the `glob` module when searching for source files within `dir`.                                   | `{}`                         |\n| `mounter`      | The name of the `Mounter` to be used to mount the discovered routes on to the `server`.                                       | `\"express\"`                  |\n| `paramPattern` | The regular expression to be used to match path parameter variables.                                                          | `/^_(.+)/`                   |\n| `registrar`    | The name of the `Registrar` used to load routes from source files in a given structure and then mount them via the `mounter`. | `\"index\"`                    |\n| `server`       | The server object (e.g. `express()`) to which the routes are to be mounted.                                                   | N/A                          |\n| `verbs`        | The verbs (corresponding to HTTP methods) to be supported. Defaults to those provided by the `mounter` if not specified.      | `mounter.getDefaultValues()` |\n\nOnly the `server` option is required. All others have defaults.\n\n### `routerify.lookup(type[, name])`\n\nThis method is primarily intended for internal use and provides a means of looking up register `Plugin` instances of a\ngiven `type`. If no `name` is provided, it will return all instances that inherit from `type`. Otherwise, this method\nwill return the first instance that inherits from `type` that has the given `name` and will throw an error if no\nmatching plugin could be found.\n\n``` javascript\nconst Plugin = require('routerify/src/plugin')\nconst Registrar = require('routerify/src/registrar')\n\nrouterify.lookup(Plugin)\n=\u003e [ ExpressMounter {}, RestifyMounter {}, IndexRegistrar {}, VerbRegistrar {} ]\nrouterify.lookup(Registrar)\n=\u003e [ IndexRegistrar {}, VerbRegistrar {} ]\nrouterify.lookup(Registrar, 'verb')\n=\u003e VerbRegistrar {}\nrouterify.lookup(Registrar, 'foo')\n=\u003e throws Error\n```\n\n### `routerify.use(plugin)`\n\nRouterify can be configured via the use of plugins, which can be registered by this method. It takes a given instance of\n`Plugin`.\n\nThe previous examples for creating your own [mounters](#create-your-own-mounter) and\n[registrars](#create-your-own-registrar) cover how to use this method.\n\n### `routerify.version`\n\nThe current version of Routerify.\n\n``` javascript\nrouterify.version\n=\u003e \"0.3.0\"\n```\n\n## Bugs\n\nIf you have any problems with Routerify or would like to see changes currently in development you can do so\n[here](https://github.com/NotNinja/routerify/issues).\n\n## Contributors\n\nIf you want to contribute, you're a legend! Information on how you can do so can be found in\n[CONTRIBUTING.md](https://github.com/NotNinja/routerify/blob/master/CONTRIBUTING.md). We want your suggestions and pull\nrequests!\n\nA list of Routerify contributors can be found in\n[AUTHORS.md](https://github.com/NotNinja/routerify/blob/master/AUTHORS.md).\n\n## License\n\nSee [LICENSE.md](https://github.com/NotNinja/routerify/raw/master/LICENSE.md) for more information on our MIT license.\n\n[![Copyright !ninja](https://cdn.rawgit.com/NotNinja/branding/master/assets/copyright/base/not-ninja-copyright-186x25.png)](https://not.ninja)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotninja%2Frouterify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotninja%2Frouterify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotninja%2Frouterify/lists"}