{"id":15068272,"url":"https://github.com/localshred/flauta","last_synced_at":"2025-04-10T16:33:41.607Z","repository":{"id":57238119,"uuid":"80852777","full_name":"localshred/flauta","owner":"localshred","description":"Rails-like router configuration library for Express apps","archived":false,"fork":false,"pushed_at":"2017-04-10T22:24:57.000Z","size":628,"stargazers_count":3,"open_issues_count":3,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-03T04:31:48.982Z","etag":null,"topics":["api","express","express-js","expressjs","http","resources","router"],"latest_commit_sha":null,"homepage":"https://localshred.github.io/flauta/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/localshred.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-03T17:36:31.000Z","updated_at":"2017-04-22T05:57:20.000Z","dependencies_parsed_at":"2022-08-26T15:01:46.485Z","dependency_job_id":null,"html_url":"https://github.com/localshred/flauta","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localshred%2Fflauta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localshred%2Fflauta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localshred%2Fflauta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localshred%2Fflauta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/localshred","download_url":"https://codeload.github.com/localshred/flauta/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239306154,"owners_count":19617223,"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":["api","express","express-js","expressjs","http","resources","router"],"created_at":"2024-09-25T01:33:06.030Z","updated_at":"2025-02-17T14:30:58.561Z","avatar_url":"https://github.com/localshred.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flauta\n\n[![npm](https://img.shields.io/npm/v/flauta.svg)](https://www.npmjs.com/package/flauta)\n[![flauta license](https://img.shields.io/npm/l/flauta.svg)](https://github.com/localshred/flauta/blob/master/COPYING)\n[![Build Status](https://travis-ci.org/localshred/flauta.svg?branch=master)](https://travis-ci.org/localshred/flauta)\n[![docs](https://img.shields.io/badge/docs-latest-lightgrey.svg)](https://localshred.github.io/flauta)\n[![view source on github](https://img.shields.io/badge/github-view_source-lightgrey.svg)](https://github.com/localshred/flauta)\n\n\nFlauta is configuration library that aims to provide a single-location routing DSL for server applications.\nIf you've used Rails before think [`config/routes.rb`][routes-rb]. Currently supports only Express.\n\nSome features include:\n\n+ Single file to declare all routes for use with Express.\n+ Simple DSL to describe route endpoints; includes regular HTTP verbs, declaring resources, and namespace support.\n+ Generated path helper functions for easily returning valid paths, with support for parameter replacements.\n+ Script to print out the route declarations in an easy-to-consume format. Invalid routes are printed with the corresponding error.\n+ Support for using `babel-register` in all requires in case you are writing application code that needs to be compiled first.\n\n## Install\n\n```shell\n$ npm install --save flauta\n\n# or\n\n$ yarn add flauta\n```\n\n## Usage\n\n1. Create a routes file somewhere in your server-side code (e.g. `server/routes.js`).\n2. Populate the routes file with two functions: `register` and `resolve`. (See below for description and example)\n3. Import your `register` function into the server file which creates your Express application and pass the express app to the `register` function.\n4. Optionally print your route declaration by running `flauta path/to/routes.js`\n4. Bask in the glory of being able to easily understand which routes your server supports.\n\n### Example\n\nDefine your routes:\n\n```javascript\n// myapp/server/routes.js\nimport R from 'ramda'\nimport flauta from 'flauta'\n\n// Provide a registration function pre-bound to your resolved routes\nexport const register = (app) =\u003e flauta.register(app, resolve())\n\n// Define and resolve your routes. \"Resolving\" means to require all the controllers and ensure\n// the expected handler functions are exported by those modules.\nexport const resolve = R.once(() =\u003e flauta.resolve([\n\n  // Configures the router to look for all your controllers in the server/controllers/ file tree.\n  // NOTE: Since flauta will require your controllers for you, the base require path MUST be an\n  // aboslute path. I recommend using path.join(__dirname, '../../../path/to/my/controllers')\n  // as it will handle relative path resolution to the current directory of the routes.js file.\n  flauta.namespace({path: '/', require: path.join(__dirname, 'controllers')}, [\n\n    // Creates a route for the path / to be served by your server/controllers/home.js controller\n    // with the exported function 'root' handling the request.\n    flauta.get('/', 'home', 'root'),\n\n    // If the resource doesn't have a corresponding controller it won't be registered\n    // and a warning will be printed when you print your route definitions (see below).\n    flauta.resource('bogus'),\n\n    // Nested namespaces join url and require paths with their parent\n    flauta.namespace({path: 'api/v1', require: 'api/v1'}, [\n      // Creates 5 endpoints for working with the \"users\" resource:\n      // + GET /api/v1/users (handler = index)\n      // + GET /api/v1/users/:id (handler = show)\n      // + POST /api/v1/users (handler = create)\n      // + PATCH /api/v1/users/:id (handler = update)\n      // + DELETE /api/v1/users/:id (handler = destroy)\n      flauta.resources('users'),\n\n      // Optionally restrict endpoints to register with 'only' or 'except' options:\n      flauta.resources('todos', {only: ['index', 'create', 'show']}),\n\n      // The inverse of above is:\n      // flauta.resources('todos', {except: ['update', 'destroy']}),\n\n      // ...\n    ]),\n\n    // ...\n  ]),\n\n  // ...\n]))\n```\n\nThen in your server file, import your `register` function and provide it with your express app:\n\n```javascript\n// server/app.js\n\nimport express from 'express'\nimport { register } from './routes'\n\nconst app = express()\nregister(app)\napp.listen(process.env.PORT)\n```\n\n## Controller definitions\n\nWith flauta, a controller is simply a normal JS file that exports the expected handler functions. These\nfunctions are exactly the same as you would write in a normal express app. If you want to have middleware\nwrapping your endpoint handler just export an array of function references, the last being the route handler.\n\n\nAn example without middleware:\n\n```javascript\n// myapp/server/controllers/home.js\n\nexport function root(req, res) {\n  res.json({ message: 'Hello, World!' })\n}\n```\n\nAn example with middelware:\n\n```javascript\n// myapp/server/controllers/home.js\n\nfunction authMiddleware(req, res, next) { ... }\nfunction loggerMiddleware(req, res, next) { ... }\n\nfunction rootHandler(req, res) {\n  res.json({ message: 'Hello, World!' })\n}\n\nexport const root = [authMiddleware, loggerMiddleware, rootHandler]\n```\n\n## Printing your route definitions\n\nIn addition to the nicety of having all your routes defined in one place, we can actually provide a way\nto print them to see the resolved state of your server side routes, meaning we can know exactly which\nmodules are required and used by our server, and which functions they expose to handle which endpoints.\nThe printer script is also babel-aware.\n\n```shell\n# If you don't need babel\n$ ./node_modules/.bin/flauta path/to/my/routes.js\n[Valid Routes]\nPath Helper     Verb      URI Pattern          Controller Module                                      Handler\n                GET       /                    /code/src/myapp/app/server/controllers/home            root\n                POST      /api/v1/users        /code/src/myapp/app/server/controllers/api/v1/users    create\n                DELETE    /api/v1/users/:id    /code/src/myapp/app/server/controllers/api/v1/users    destroy\napi-v1-users    GET       /api/v1/users        /code/src/myapp/app/server/controllers/api/v1/users    index\napi-v1-user     GET       /api/v1/users/:id    /code/src/myapp/app/server/controllers/api/v1/users    show\n                PATCH     /api/v1/users/:id    /code/src/myapp/app/server/controllers/api/v1/users    update\n                POST      /api/v1/todos        /code/src/myapp/app/server/controllers/api/v1/todos    create\napi-v1-todos    GET       /api/v1/todos        /code/src/myapp/app/server/controllers/api/v1/todos    index\napi-v1-todo     GET       /api/v1/todos/:id    /code/src/myapp/app/server/controllers/api/v1/todos    show\n[Invalid Routes]\nVerb      URI Pattern    Controller Module                               Handler    Error\nPOST      /bogus         /code/src/myapp/app/server/controllers/bogus    create     Cannot find module '/code/src/myapp/app/server/controllers/bogus'\nDELETE    /bogus/:id     /code/src/myapp/app/server/controllers/bogus    destroy    Cannot find module '/code/src/myapp/app/server/controllers/bogus'\nGET       /bogus         /code/src/myapp/app/server/controllers/bogus    index      Cannot find module '/code/src/myapp/app/server/controllers/bogus'\nGET       /bogus/:id     /code/src/myapp/app/server/controllers/bogus    show       Cannot find module '/code/src/myapp/app/server/controllers/bogus'\nPATCH     /bogus/:id     /code/src/myapp/app/server/controllers/bogus    update     Cannot find module '/code/src/myapp/app/server/controllers/bogus'\n```\n\n```shell\n# Or if you need to use babel-register\n$ ./node_modules/.bin/flauta --babel -- path/to/my/routes.js\n```\n\n## Using path helpers\n\n\n```javascript\n// myapp/server/routes.js\nimport R from 'ramda'\nimport flauta from 'flauta'\n\nexport const resolve = R.once(() =\u003e flauta.resolve([\n  flauta.namespace({path: '/', require: path.join(__dirname, 'controllers')}, [\n    flauta.resources('users'),\n\n    flauta.namespace({path: 'api/v1', require: 'api/v1'}, [\n      flauta.resources('todos'),\n    ]),\n  ]),\n]))\n\n// somewhere else in your app\nimport { resolve } from '../path/to/server/routes'\n\nconst { paths } = resolve()\n\npaths.users() // =\u003e '/users'\npaths.user({ id: '123' }) // =\u003e '/users/123'\n\npaths['api-v1-todos']() // =\u003e '/api/v1/todos'\npaths['api-v1-todo']({ id: '123' }) // =\u003e '/api/v1/todos/123'\n```\n\n  [routes-rb]: http://guides.rubyonrails.org/routing.html#listing-existing-routes \"Rails Routing Guide\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalshred%2Fflauta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flocalshred%2Fflauta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalshred%2Fflauta/lists"}