{"id":19383316,"url":"https://github.com/alignable/js-routes-loader","last_synced_at":"2026-05-07T19:04:41.766Z","repository":{"id":44177828,"uuid":"109875013","full_name":"Alignable/js-routes-loader","owner":"Alignable","description":"A webpack loader for parsing route definitions in json files and wrapping them with a simple javascript api.","archived":false,"fork":false,"pushed_at":"2023-11-28T03:37:38.000Z","size":2447,"stargazers_count":1,"open_issues_count":23,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-07T06:50:01.707Z","etag":null,"topics":["routes","webpack-loader"],"latest_commit_sha":null,"homepage":"","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/Alignable.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-07T18:32:13.000Z","updated_at":"2019-08-21T18:04:19.000Z","dependencies_parsed_at":"2024-11-10T09:26:07.585Z","dependency_job_id":"0064f6d7-d739-4aa3-893f-af8945fea158","html_url":"https://github.com/Alignable/js-routes-loader","commit_stats":{"total_commits":26,"total_committers":2,"mean_commits":13.0,"dds":"0.038461538461538436","last_synced_commit":"dd5a6880c1573f5e874986a8e3f3aff2634818f3"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alignable%2Fjs-routes-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alignable%2Fjs-routes-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alignable%2Fjs-routes-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alignable%2Fjs-routes-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alignable","download_url":"https://codeload.github.com/Alignable/js-routes-loader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240521052,"owners_count":19814694,"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":["routes","webpack-loader"],"created_at":"2024-11-10T09:25:30.997Z","updated_at":"2026-05-07T19:04:36.733Z","avatar_url":"https://github.com/Alignable.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm][npm]][npm-url]\n[![deps][deps]][deps-url]\n[![test][test]][test-url]\n[![coverage][cover]][cover-url]\n\n# js-routes-loader\n\nA [webpack](https://github.com/webpack/webpack) loader for parsing route definitions in json files and wrapping them with a simple javascript api.\n\n## Install\n\n```bash\nnpm i -D js-routes-loader\n```\n\n## Usage\n\nSuppose we have the following routes file:\n\n**routes/starships.json**\n```js\n{\n  \"routes\": [\n    {\n      \"name\": \"starships\",\n      \"path\": \"/posts\"\n    },\n    {\n      \"name\": \"starship\",\n      \"path\": \"/starships/:id\",\n      \"required_params\": [\"id\"]\n    }\n  ]\n}\n```\n\nConfigure the loader in webpack to apply to all your routes files\n**webpack.config.js**\n```js\nmodule.exports = {\n  module: {\n    loaders: [\n      {\n        test: /routes/.*\\.json$/,\n        loader: 'js-routes-loader',\n      },\n    ],\n  },\n};\n```\n\n**index.js**\n```js\nconst routes = require('./routes/starships.json');\n\nroutes.starships();             // '/starships'\nroutes.starships('enterprise'); // '/starships/enterprise'\n```\n\n## Details\n\n### Routes JSON Format\n\nThe routes json file defines the set of routes available in your app.\nSuppose we had an web app with a REST api for  managing starships and their crew.\nIts routes file might look like this:\n\n**startships.json**\n```js\n{\n  \"routes\": [\n    {\n      \"name\": \"starships\",\n      \"path\": \"/starships(.:format)\",\n      \"required_params\": [],\n      \"optional_params\": [\"format\"],\n      \"methods\": ['GET', 'POST']\n    },\n    {\n      \"name\": \"starship\",\n      \"path\": \"/starships/:id(.:format)\",\n      \"required_params\": [\"id\"],\n      \"optional_params\": [\"format\"],\n      \"methods\": [\"GET\", \"PUT\", \"PATCH\", \"DELETE\"]\n    },\n    {\n      \"name\": \"starshipCrewMembers\",\n      \"path\": \"/starships/:starship_id/crew_members(.:format)\",\n      \"required_params\": [\"starship_id\"],\n      \"optional_params\": [\"format\"],\n      \"methods\": [\"GET\", \"POST\"]\n    },\n    {\n      \"name\": \"starshipCrewMember\",\n      \"path\": \"/starships/:starship_id/crew_members/:id(.:format)\",\n      \"required_params\": [\"starship_id\", \"id\"],\n      \"optional_params\": [\"format\"],\n      \"methods\": [\"GET\", \"PUT\", \"PATCH\", \"DELETE\"]\n    },\n    // more routes\n  ]\n}\n```\n\nEach route objects has the following for properties:\n\n|Property|Type |Description|Required|\n|--------|:---:|-----------|:------:|\n|**name**|`String`| The name of the route. Must be a valid javascript function name and unique. | Yes |\n|**path**|`String`| The 'spec' of the routes path. Required parameters should be encoded as `:param`. | Yes |\n|**required_params** |`Array`| A list of required parameters that appear in `path`. | No |\n|**optional_params** |`Array`| A list of optional parameters that appear in `path`. | No |\n|**methods** |`Array`| A list of http methods that the route supports. | No |\n \nIn production the routes json file will typically be created by exporting the routes from your backend application.  \n\n### Routes Javascript API\n\nThe js-routes-loader converts each route specified in the json file into a javascript function that returns a wrapper around fetch object.\n\nImporting the startships.json file above results is equivalent to four functions with the following signature:\n\n```js\nconst routes = {\n  starships: (options = {}) =\u003e fatchWrapper(....),\n  starship: (id, options = {}) =\u003e fatchWrapper(....),\n  starshipCrewMembers: (starthip_id, options = {}) =\u003e fatchWrapper(....),\n  starshipCrewMember: (starthip_id, id, options = {}) =\u003e fatchWrapper(....),\n};\n``` \n\n#### `path`\nReturns the path resulting from replacing the required parameters in the path with supplied parameters.\n\nExample: The path to the list of all starships\n```js\nroutes.starships().path; // '/starships'\n```\n\nor the path to the crew member with `id=12` on the starship `enterprise` would be:\n```js\nroutes.starshipCrewMember('enterprise', 12).path; // '/starships/enterprise/crewMembers/12'\n```\n\n#### `options`\nEach route method takes an optional map of options than affect the path the route generates.\n\n#### `options[optional_params]`\n\nParameters who's keys match entries in the route's `optional_params` array will be appended replaced in the path.\n\nExample: The path to the crew member with `id=12` on the starship `enterprise` in json format would be:\n```js\nroutes.starshipCrewMember('enterprise', 12, { format: 'json' }).path; // '/starships/enterprise/crewMembers/12.json'\n```\n\n#### `options[queryParams]`\n\nAny query string parameters can be passed to the route and will be appended to the path.\n\nExample: The path to search for 'federation' starships in the 'constitution' class would be:\n```js\nroutes.starships({ affiliation: 'federation', class: 'constitution'}).path; // '/starships?affiliation=federation\u0026class=constitution'\n```\n\n#### `options[anchor]`\nThe `anchor` option is special will be appended to the path as an anchor tag after the query string parameters.\n\nExample: the path to all 'klingon' starhips with the anchor 'bird of prey' would be:\n```js\nroutes.starships({ affiliation: 'klingon', anchor: 'bird of prey'}).path; // '/starships?affiliation=kligon#bird%20of%20prey'\n```\n\n#### `methods`\nReturns the methods supported by the route:\n\n```js\nroutes.starships().methods;             // ['GET', 'POST']\nroutes.starships('enterprise').methods; // ['GET', 'PUT', 'PATCH', 'DELETE']\n```\n\nIf the methods array is missing or empty it is assumed that all methods are supported. What's the use of a route that supports no ways of calling it? :confused:.\n\n### `fetch` wrappers\n\nHaving easy access to the applications paths is great but given a path you probably want to make some sort of request against that path.\nBe default `js-route-loader` ships with a simple wrapper around the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). The wrapper does two things. First it checks the route supports the http method you are trying to fetch.\n Second it curries the path for the route into the call to fetch.\n\nExample:\n```js\nroutes.starshipCrewMember('enterprise').fetch({method: 'POST', body: JSON.stringify({ name: 'James T. Kirk', rank: 'Captain' }));\n// Equivalent to\nfetch('/starships/enterprise/crewMembers', {method: 'POST', body: JSON.stringify({ name: 'James T. Kirk', rank: 'Captain' }) });\n``` \n\nYou might combine these fetch methods like this:\n```js\nconst readyAwayParty = async () =\u003e {\n  const response = await routes.starshipCrewMembers('enterprise', { rank: 'ensign', shirt: 'red' }).fetch({method: 'GET'});\n  const ensigns = await response.json();\n  const firstEnsign = ensigns[0];\n  await routes.starshipCrewMember('enterprise', firstEnsign.id).patch( {status: 'away', phasers: 'stun'}).fetch({method: 'GET'});\n  return firstEnsign;\n};\n\n\nexploreStrangeNewWorld(readyAwayParty())\n  .then((discoveredLifeForms) =\u003e {\n    console.log(`New life forms discovered ${discoveredLifeForms}`);\n  })\n  .catch((lostCrew) =\u003e {\n    console.log(\"He's dead Jim\");\n    lostCrew.forEach((crew) =\u003e routes.starshipCrewMember('enterprise', crew.id).fetch({method: 'DELETE'}));\n  });\n```\n\nMore information on using the fetch API can be found in the [Using Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) documentation.\n\nIf you are using JS Routes Loader in browsers without fetch support make sure to include the [Fetch polyfil](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) in you webpack.\n\n### Adding your own `fetch` Wrapper\n\nBy default `js-routes-loader` uses a thin wrapper around `fetch`.\nHowever, you might want to supply your own featch wrapper to adjust the behavior.\nFor example, suppose all your requests are going to be json and you want to set json headers and always parse the response as json.\nYou would define a fetch wrapper like this by extending the FetchWrapper class:\n\n**JsonFetchWrapper.js**\n```js\nimport { FetchWrapper } from 'js-routes-loader';\n\nconst jsonOptions = {\n  headers: {\n    'Accept': 'application/json',\n    'Content-Type': 'application/json',\n  },\n};\n\nclass JsonFetchWrapper extends FetchWrapper {\n  fetch(options) {\n    this.checkMethod(options.method);\n    return fetch(this.path, Object.assign(jsonOptions, options))\n      .then((response) =\u003e response.json());\n  }\n}\n\nexport default (path, methods) =\u003e new JsonFetchWrapper(path, methods);\n```\n\nNow either configure `js-routes-loader` to use your fetch handler for all files:\n\n**webpack.config.js**\n```js\nmodule.exports = {\n  module: {\n    loaders: [\n      {\n        test: /routes/.*\\.json$/,\n        use: [{\n          loader: 'js-routes-loader',\n          options: {\n            fetch: require.resolve('./JsonFetchWrapper'),\n          },\n        }],\n      },\n    ],\n  },\n};\n```\n\nor configure the fetch hanlder via a query parameter in the require statement:\n\n```js\nconst routes = require('!!js-routes-loader?fetch=./JsonFetchWrapper!./routes/starships.json');\n```\n\n[npm]: https://img.shields.io/npm/v/js-routes-loader.svg\n[npm-url]: https://npmjs.com/package/js-routes-loader\n\n[deps]: https://david-dm.org/Alignable/js-routes-loader.svg\n[deps-url]: https://david-dm.org/Alignable/js-routes-loader\n\n[test]: http://img.shields.io/travis/Alignable/js-routes-loader.svg\n[test-url]: https://travis-ci.org/Alignable/js-routes-loader\n\n[cover]: https://codecov.io/gh/Alignable/js-routes-loader/branch/master/graph/badge.svg\n[cover-url]: https://codecov.io/gh/Alignable/js-routes-loader\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falignable%2Fjs-routes-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falignable%2Fjs-routes-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falignable%2Fjs-routes-loader/lists"}