{"id":22202155,"url":"https://github.com/rumkin/hall","last_synced_at":"2025-06-26T17:32:18.949Z","repository":{"id":35770914,"uuid":"40050548","full_name":"rumkin/hall","owner":"rumkin","description":"Unified http router for middlewares","archived":false,"fork":false,"pushed_at":"2017-02-11T13:48:24.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-01T15:47:18.071Z","etag":null,"topics":["filter-requests","javascript","middleware","router"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/hall","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rumkin.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-01T15:19:05.000Z","updated_at":"2016-10-23T22:00:57.000Z","dependencies_parsed_at":"2022-08-26T23:02:14.647Z","dependency_job_id":null,"html_url":"https://github.com/rumkin/hall","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rumkin/hall","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Fhall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Fhall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Fhall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Fhall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rumkin","download_url":"https://codeload.github.com/rumkin/hall/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rumkin%2Fhall/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262113220,"owners_count":23260981,"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":["filter-requests","javascript","middleware","router"],"created_at":"2024-12-02T16:12:34.926Z","updated_at":"2025-06-26T17:32:18.920Z","avatar_url":"https://github.com/rumkin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hall\n\nUnified HTTP middleware router. It works with express, connect and native http\nserver. It's goal is provide routring for distributable and modular\nweb applications and support standard behavior.\n\n![Travis](https://img.shields.io/travis/rumkin/hall/master.svg)\n\n\n## Installation\n\n```shell\nnpm install hall\n```\n\n## Usage\n\nExample of middleware factory.\n\n```javascript\nconst hall = require('hall');\nconst connect = require('connect');\n\n// Middleware factory\nconnect()\n    .use(hall((router) =\u003e {\n        router.get('/products/:id', (req, res) =\u003e {\n            // ...\n        });\n    });\n```\n\nExample of router factory.\n\n```javascript\nconst hall = require('hall');\nconst connect = require('connect');\n\n// Router instance\nconst router = hall();\n\nrouter.resource('/products/:id')\n.get((req, res, next) =\u003e {\n    // Return product...\n})\n.put((req, res, next) =\u003e {\n    // Update product...\n})\n.delete((req, res, next) =\u003e {\n    // Delete product...\n});\n\n\nrouter.get('/products/:id/reviews', (req, res) =\u003e {\n    // ...\n});\n\nconnect().use(router);\n```\n\nResources are differs from single routes. It processing before routes. If\nresource exists but method not defined than response gets 405 status code\n(method not allowed).\n\n## API\n\n### router.resource(route: string[, handlers: Object]) =\u003e Resource\n\nAdd resource. If route is defined return existing resource instance. If handlers\nis an object use property names as methods names and values as a handlers:\n\n```javascript\nrouter.resource('/users/:id')\n.get((req, res, next) =\u003e {\n    // ...\n})\n.put((req, res, next) =\u003e {\n    // ...\n});\n\nrouter.resource('/docs/:id', {\n    get(req, res, next) {\n        // get...\n    },\n    delete(req, res, next) {\n        // delete...\n    }\n});\n```\n\n### Methods\n\nRouter has methods `before`, `after`, `filter` and `use`. This methods allow\nto control process of request preprocessing and filtering. Note that before and after\nhandlers will not be called if there is no matching routes.\n\n```javascript\n\nvar router = hall();\n\n// Preprocess request\nrouter.before((req, res, next) =\u003e {\n    req.version = req.headers['X-API-VERSION'];\n    next();\n});\n\n// Pass only 2.0 API requests.\nrouter.filter((req) =\u003e {\n    return req.version === '2.0'\n});\n\nrouter.after((error, req, res, next) =\u003e {\n    // Got an error or nothing is found...\n});\n\nrouter.get('/product/:id', (req, res, next) =\u003e {\n    // Get and render product\n    res.end();\n});\n```\n\n### HTTP Methods\n\nMethods to bind http methods routes. There is several supported HTTP methods:\n\n* `GET`\n* `POST`\n* `PUT`\n* `DELETE`\n* `PATCH`\n* `HEAD`\n\nEach HTTP-method has it's own lowercased alias:\n\n```javascript\nrouter.get('/', (req, res, next) =\u003e {\n  // ...\n});\n\nrouter.post('/', (req, res, next) =\u003e {\n  // ...\n});\n\nrouter.patch('/', (req, res, next) =\u003e {\n  // ...\n});\n```\n\nAlso route could be instance of `hall.RouteParser`:\n\n```javascript\nrouter.get(new hall.RouteParser('/some/:id'), (req, res, next) =\u003e {\n  // ...\n});\n```\n\n\n### Filter\n\nFilter method allow to filter requests in smarter way. It's using for dynamic request filtering. Filter method should\nreturn boolean, promise or use methods;\n\n```javascript\n// Boolean\nrouter.filter((req) =\u003e {\n    return req.hostname === 'localhost';\n});\n\n// Promise\nrouter.filter((req) =\u003e {\n    return new Promise((resolve, reject) =\u003e {\n        // Do some async job\n    });\n});\n\n// Methods\nrouter.filter((req, next, skip) =\u003e {\n    if (req.hostname === 'localhost') {\n        next();\n    } else {\n        skip();\n    }\n});\n```\n\n### Use\n\nMethod `use` is context dependent and it will call before if there is no routes defined and after in other way.\n\n```javascript\nrouter.use((req, res, next) =\u003e {\n    // Call before\n    next();\n});\n\nrouter.get('/product/:id', (req, res, next) =\u003e {\n    // Get and render product\n    res.end();\n});\n\nrouter.use((req, res, next) =\u003e {\n    // Call after\n    next();\n```\n\n## Workflow\n\nRouter will not call any method if request has no matching url. This is made for request isolation and high productivity.\nIf you have some job which should be done for each request move it to previous loop.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frumkin%2Fhall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frumkin%2Fhall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frumkin%2Fhall/lists"}