{"id":13799419,"url":"https://github.com/tunnckoCore/koa-rest-router","last_synced_at":"2025-05-13T08:31:09.593Z","repository":{"id":40950337,"uuid":"70716623","full_name":"tunnckoCore/koa-rest-router","owner":"tunnckoCore","description":"Most powerful, flexible and composable router for building enterprise RESTful APIs easily!","archived":false,"fork":false,"pushed_at":"2023-01-23T18:06:18.000Z","size":629,"stargazers_count":68,"open_issues_count":13,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-11T04:45:33.585Z","etag":null,"topics":["composable","fast","flexible","koa2","middleware","powerful","rest-api","restful","restful-api","router","webservices"],"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/tunnckoCore.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-12T15:59:51.000Z","updated_at":"2024-11-19T13:09:44.000Z","dependencies_parsed_at":"2023-02-13T01:46:11.832Z","dependency_job_id":null,"html_url":"https://github.com/tunnckoCore/koa-rest-router","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tunnckoCore%2Fkoa-rest-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tunnckoCore%2Fkoa-rest-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tunnckoCore%2Fkoa-rest-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tunnckoCore%2Fkoa-rest-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tunnckoCore","download_url":"https://codeload.github.com/tunnckoCore/koa-rest-router/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253903704,"owners_count":21981734,"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":["composable","fast","flexible","koa2","middleware","powerful","rest-api","restful","restful-api","router","webservices"],"created_at":"2024-08-04T00:01:02.540Z","updated_at":"2025-05-13T08:31:09.305Z","avatar_url":"https://github.com/tunnckoCore.png","language":"JavaScript","funding_links":[],"categories":["仓库"],"sub_categories":["中间件"],"readme":"# koa-rest-router [![NPM version](https://img.shields.io/npm/v/koa-rest-router.svg?style=flat)](https://www.npmjs.com/package/koa-rest-router) [![NPM monthly downloads](https://img.shields.io/npm/dm/koa-rest-router.svg?style=flat)](https://npmjs.org/package/koa-rest-router) [![npm total downloads][downloads-img]][downloads-url]\n\n\u003e Most powerful, flexible and composable router for building enterprise RESTful APIs easily!\n\n[![codeclimate][codeclimate-img]][codeclimate-url] \n[![codestyle][standard-img]][standard-url] \n[![linux build][travis-img]][travis-url] \n[![windows build][appveyor-img]][appveyor-url] \n[![codecov][coverage-img]][coverage-url] \n[![dependency status][david-img]][david-url]\n\n_You might also be interested in [gibon][] - a minimal \u0026 functional 600 bytes client-side router._\n\n## Highlighs\n- **production:** ready for and used in\n- **composability:** grouping multiple resources and multiple routers\n- **flexibility:** overriding controller and request methods, plus custom prefixes\n- **compatibility:** accepts both old and modern middlewares without deprecation messages\n- **powerful:** multiple routers on same [koa][] app - even can combine multiple routers\n- **light:** not poluting your router instance and app - see `.loadMethods`\n- **backward compatible:** works on koa v1 - use `.legacyMiddleware`\n- **maintainability:** very small, beautiful, maintainable and commented codebase\n- **stability:** strict semantic versioning and very well documented, based on [koa-better-router][]\n- **open:** love PRs for features, issues and recipes - [Contribute a recipe?](#contributing-recipes) See the [recipes](https://github.com/tunnckoCore/koa-better-router/tree/master/recipes) of [koa-better-router][]\n\n## Table of Contents\n- [Quickstart](#quickstart)\n  * [Controller methods mapping](#controller-methods-mapping)\n  * [Overriding controller methods](#overriding-controller-methods)\n  * [Overriding request methods](#overriding-request-methods)\n- [Install](#install)\n- [Usage](#usage)\n- [API](#api)\n  * [KoaRestRouter](#koarestrouter)\n  * [.createResource](#createresource)\n  * [.addResource](#addresource)\n  * [.getResource](#getresource)\n  * [.resource](#resource)\n  * [.addResources](#addresources)\n  * [.getResources](#getresources)\n  * [.groupResources](#groupresources)\n- [Related](#related)\n- [Contributing](#contributing)\n  * [Contributing Recipes](#contributing-recipes)\n- [Building docs](#building-docs)\n- [Running tests](#running-tests)\n- [Author](#author)\n- [License](#license)\n\n_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_\n\n**ProTip:** Checkout [koa-better-router API](https://github.com/tunnckoCore/koa-better-router#api) too to know what more methods comes with this.\n\n## Quickstart\n\u003e This router uses [koa-better-router][], so you should review its API documentation to get more info how the things are working and what more methods are exposed.\n\n### Controller methods mapping\n\u003e In addition this router allows you to override the controller methods which will be used in certain route path.\n\n**Defaults**\n\n| Request method | Route path | Controller method |\n| --- | --- | --- |\n| GET | `/users` | `index` |\n| GET | `/users/new ` | `new` |\n| POST | `/users` | `create` |\n| GET | `/users/:user` | `show` |\n| GET | `/users/:user/edit` | `edit` |\n| PUT | `/users/:user` | `update` |\n| DELETE | `/users/:user` | `remove` |\n\n**Example**\n\n```js\nlet Router = require('koa-rest-router')\nlet router = Router()\n\nrouter.resource('users', {\n  // GET /users\n  index: (ctx, next) =\u003e {},\n\n  // GET /users/new\n  new: (ctx, next) =\u003e {},\n\n  // POST /users\n  create: (ctx, next) =\u003e {},\n\n  // GET /users/:user\n  show: (ctx, next) =\u003e {},\n\n  // GET /users/:user/edit\n  edit: (ctx, next) =\u003e {},\n\n  // PUT /users/:user\n  update: (ctx, next) =\u003e {},\n\n  // DELETE /users/:user\n  remove: (ctx, next) =\u003e {}\n})\n\nlet users = router.getResource('users')\n\nconsole.log(users.length) // =\u003e 7\nconsole.log(users) // =\u003e Array Route Objects\n\nconsole.log(router.routes.length) // =\u003e 7\nconsole.log(router.resources.length) // =\u003e 1\n```\n\n**Note:** Multiple middlewares can be passed on each. Also combining old and modern koa middlewares, so both generator functions and normal functions.\n\n### Overriding controller methods\n\u003e You easily can override the defaults by passing `options.map` object with key/value pairs where the key represents the original, and value is a string containing the wanted override.\n\n**Example**\n\n```js\nlet router = require('koa-rest-router')()\n\nlet options = {\n  map: {\n    index: 'foo',\n    new: 'bar',\n    create: 'baz',\n    show: 'qux',\n  }\n}\n\nrouter.resource('users', {\n  // GET /users\n  foo: (ctx, next) =\u003e {},\n\n  // GET /users/new\n  bar: (ctx, next) =\u003e {},\n\n  // POST /users\n  baz: (ctx, next) =\u003e {},\n\n  // GET /users/:user\n  qux: (ctx, next) =\u003e {},\n\n  // ... etc\n}, options)\n```\n\n### Overriding request methods\n\u003e In some cases in guides the REST routes uses different request methods and that field is not clear enough. So every sane router should allow overriding such things, so we do it. By default for updating is used `PUT`, for deleting/removing is `DELETE`. You can override this methods to use `POST` instead, so ...\n\n**Example**\n\n```js\nlet router = require('koa-rest-router')()\n\nlet options = {\n  methods: {\n    put: 'POST'\n  }  \n}\n\nrouter.resource('cats', {\n  // POST /cats/:cat\n  update: (ctx, next) =\u003e {}\n}, options)\n```\n\nAnd you can combine both overriding variants, of course\n\n**Example**\n\n```js\nlet router = require('koa-rest-router')()\n\nlet options = {\n  methods: {\n    put: 'POST'\n  },\n  map: {\n    update: 'foobar'\n  }\n}\n\nrouter.resource('cats', {\n  // POST /cats/:cat\n  foobar: (ctx, next) =\u003e {}\n}, options)\n```\n\n## Install\n\u003e Install with [npm](https://www.npmjs.com/)\n\n```sh\n$ npm i koa-rest-router --save\n```\n\n## Usage\n\u003e For more use-cases see the [tests](./test.js)\n\n```js\nlet router = require('koa-rest-router')()\n\n// or\n\nlet Router = require('koa-rest-router')\nlet apiRouter = Router({ prefix: '/api/v1' })\n```\n\n## API\n\n### [KoaRestRouter](index.js#L77)\n\u003e Initialize `KoaRestRouter` with optional `options`, directly passed to [koa-better-router][] and this package inherits it. So you have all methods and functionality from the awesome [koa-better-router][] middleware.\n\n**Params**\n\n* `[options]` **{Object}**: passed directly to [koa-better-router][], in addition we have 2 more options here.    \n* `[options.methods]` **{Object}**: override request methods to be used    \n* `[options.map]` **{Object}**: override controller methods to be called    \n\n**Example**\n\n```js\nlet Router = require('koa-rest-router')\nlet api = Router({ prefix: '/api/v1' })\n\n// - can have multiples middlewares\n// - can have both old and modern middlewares combined\napi.resource('companies', {\n  index: function (ctx, next) {},\n  show: function (ctx, next) {},\n  create: function (ctx, next) {}\n  // ... and etc\n})\n\nconsole.log(api.routes.length) // 7\nconsole.log(api.resources.length) // 1\n\napi.resource('profiles', {\n  index: function (ctx, next) {},\n  show: function (ctx, next) {},\n  create: function (ctx, next) {}\n  // ... and etc\n})\n\nconsole.log(api.routes.length) // 14\nconsole.log(api.resources.length) // 2\n\nlet Koa = require('koa') // Koa v2\nlet app = new Koa()\n\nlet basic = Router() // prefix is `/` by default\nbasic.extend(api)\n\napp.use(api.middleware())\napp.use(basic.middleware())\n\napp.listen(4444, () =\u003e {\n  console.log('Open http://localhost:4444 and try')\n  // will output 2x14 links\n  // - 14 links on `/api/v1` prefix\n  // - 14 links on `/` prefix\n  api.routes.forEach((route) =\u003e {\n    console.log(`${route.method} http://localhost:4444${route.path}`)\n  })\n  basic.routes.forEach((route) =\u003e {\n    console.log(`${route.method} http://localhost:4444${route.path}`)\n  })\n})\n```\n\n### [.createResource](index.js#L194)\n\u003e Core method behind `.resource` for creating single resource with a `name`, but without adding it to `this.routes` array. You can override any defaults - default request methods and default controller methods, just by passing respectively `opts.methods` object and `opts.map` object. It uses [koa-better-router][]'s `.createRoute` under the hood.\n\n**Params**\n\n* `name` **{String|Object}**: name of the resource or `ctrl`    \n* `ctrl` **{Object}**: controller object to be called on each endpoint, or `opts`    \n* `opts` **{Object}**: optional, merged with options from constructor    \n* `returns` **{KoaRestRouter}** `this`: instance for chaining  \n\n**Example**\n\n```js\nlet router = require('koa-rest-router')({\n  prefix: '/api'\n}).loadMethods()\n\n// The server part\nlet body = require('koa-better-body')\nlet Koa = require('koa')\nlet app = new Koa()\n\n// override request methods\nlet methods = {\n  put: 'POST'\n  del: 'POST'\n}\n\n// override controller methods\nlet map = {\n  index: 'list',\n  show: 'read',\n  remove: 'destroy'\n}\n\n// notice the body should be invoked explicitly\n// with or without options object, no matter\nlet updateMiddlewares = [body(), (ctx, next) =\u003e {\n  ctx.body = `This method by default is triggered with PUT requests only.`\n  ctx.body = `${ctx.body} But now it is from POST request.`\n  return next()\n}, function * (next) =\u003e {\n  this.body = `${this.body} Incoming data is`\n  this.body = `${this.body} ${JSON.stringify(this.request.fields, null, 2)}`\n  yield next\n}]\n\n// create actual resource\nlet cats = router.createResource('cats', {\n  list: [\n    (ctx, next) =\u003e {\n      ctx.body = `This is GET ${ctx.route.path} route with multiple middlewares`\n      return next()\n    },\n    function * (next) {\n      this.body = `${this.body} and combining old and modern middlewares.`\n      yield next\n    }\n  ],\n  read: (ctx, next) =\u003e {\n    ctx.body = `This is ${ctx.route.path} route.`\n    ctx.body = `${ctx.body} And param \":cat\" is ${ctx.params.cat}.`\n    ctx.body = `${ctx.body} By default this method is called \"show\".`\n    return next()\n  },\n  update: updateMiddlewares,\n  destroy: (ctx, next) =\u003e {\n    ctx.body = `This route should be called with DELETE request, by default.`\n    ctx.body = `${ctx.body} But now it request is POST.`\n    return next()\n  }\n}, {map: map, methods: methods})\n\nconsole.log(cats)\n// =\u003e array of \"Route Objects\"\n\n// router.routes array is empty\nconsole.log(router.getRoutes()) // =\u003e []\n\n// register the resource\nrouter.addResource(cats)\n\nconsole.log(router.routes.length) // =\u003e 7\nconsole.log(router.getRoutes().length) // =\u003e 7\nconsole.log(router.getRoutes()) // or router.routes\n// =\u003e array of \"Route Objects\"\n\napp.use(router.middleware())\n\napp.listen(5000, () =\u003e {\n  console.log(`Server listening on http://localhost:5000`)\n  console.log(`Try to open these routes:`)\n\n  router.routes.forEach((route) =\u003e {\n    console.log(`${route.method}` http://localhost:5000${route.path}`)\n  }))\n})\n```\n\n### [.addResource](index.js#L253)\n\u003e Simple method that is alias of `.addRoutes` and `.addResources`, but for adding single resource. It can accepts only one `resource` object.\n\n**Params**\n\n* `resource` **{Array}**: array of route objects, known as _\"Resource Object\"_    \n* `returns` **{KoaRestRouter}** `this`: instance for chaining  \n\n**Example**\n\n```js\nlet Router = require('koa-rest-router')\nlet api = new Router({\n  prefix: '/'\n})\n\nconsole.log(api.resources.length) // 0\nconsole.log(api.routes.length) // 0\n\napi.addResource(api.createResource('dragons'))\n\nconsole.log(api.resources.length) // 1\nconsole.log(api.routes.length) // 7\n\nconsole.log(api.getResource('dragons'))\n// array of route objects\n// =\u003e [\n//   { prefix: '/', route: '/dragons', path: '/dragons', ... }\n//   { prefix: '/', route: '/dragons/:dragon', path: '/dragons/:dragon', ... }\n//   ... and 5 more routes\n// ]\n```\n\n### [.getResource](index.js#L291)\n\u003e Get single resource by `name`. Special case is resource to the `/` prefix. So pass `/` as `name`. See more on what are the _\"Route Objects\"_ in the [koa-better-router][] docs. What that method returns, I call _\"Resource Object\"_ - array of _\"Route Objects\"_\n\n**Params**\n\n* `name` **{String}**: name of the resource, plural    \n* `returns` **{Array|Null}**: if resource with `name` not found `null, otherwise array of route objects - that array is known as Resource Object  \n\n**Example**\n\n```js\nlet api = require('koa-rest-router')({\n  prefix: '/api/v2'\n})\n\nlet frogs = api.createResource('frogs')\nlet dragons = api.createResource('dragons')\n\nconsole.log(api.getResource('frogs'))\n// array of route objects\n// =\u003e [\n//   { prefix: '/api/v2', route: '/frogs', path: '/api/v2/frogs', ... }\n//   { prefix: '/api/v2', route: '/frogs/:frog', path: '/api/v2/frogs/:frog', ... }\n//   ... and 5 more routes\n// ]\n\nconsole.log(api.getResources().length) // 2\n```\n\n### [.resource](index.js#L403)\n\u003e Creates a resource using `.createResource` and adds the resource routes to the `this.routes` array, using `.addResource`. This is not an alias! It is combination of two methods. Methods that are not defined in given `ctrl` (controller) returns by default `501 Not Implemented`. You can override any defaults - default request methods and default controller methods, just by passing respectively `opts.methods` object and `opts.map` object.\n\n**Params**\n\n* `name` **{String|Object}**: name of the resource or `ctrl`    \n* `ctrl` **{Object}**: controller object to be called on each endpoint, or `opts`    \n* `opts` **{Object}**: optional, merged with options from constructor    \n* `returns` **{KoaRestRouter}** `this`: instance for chaining  \n\n**Example**\n\n```js\nlet Router = require('koa-rest-router')\n\nlet api = new Router({ prefix: '/api/v3' })\nlet router = new Router() // on `/` prefix by default\n\n// All of the controller methods\n// can be remap-ed. using `opts.map`\n// try to pass `{ map: { index: 'home' } }` as options\n\napi.resource('users', {\n  // GET /users\n  index: [(ctx, next) =\u003e {}, (ctx, next) =\u003e {}],\n\n  // GET /users/new\n  new: (ctx, next) =\u003e {},\n\n  // POST /users\n  create: (ctx, next) =\u003e {},\n\n  // GET /users/:user\n  show: [(ctx, next) =\u003e {}, function * (next) {}],\n\n  // GET /users/:user/edit\n  edit: (ctx, next) =\u003e {},\n\n  // PUT /users/:user\n  // that `PUT` can be changed `opts.methods.put: 'post'`\n  update: (ctx, next) =\u003e {},\n\n  // DELETE /users/:user\n  // that `DELETE` can be changed `opts.methods.delete: 'post'`\n  remove: (ctx, next) =\u003e {}\n})\n\n// notice the `foo` method\nrouter.resource({\n  // GET /\n  foo: [\n    (ctx, next) =\u003e {\n      ctx.body = `GET ${ctx.route.path}`\n      return next()\n    },\n    function * (next) {\n      ctx.body = `${this.body}! Hello world!`\n      yield next\n    }\n  ],\n  // GET /:id, like /123\n  show: (ctx, next) =\u003e {\n    ctx.body = JSON.stringify(ctx.params, null, 2)\n    return next()\n  }\n}, {\n  map: {\n    index: 'foo'\n  }\n})\n\napi.routes.forEach(route =\u003e console.log(route.method, route.path))\nrouter.routes.forEach(route =\u003e console.log(route.method, route.path))\n\n// Wanna use only one router?\nlet fooRouter = new Router()\nlet Koa = require('koa')\nlet app = new Koa()\n\nfooRouter.addRoutes(api.getResources(), router.getRoutes())\n\nconsole.log(fooRouter.routes)\nconsole.log(fooRouter.routes.length) // 14\n\napp.use(fooRouter.middleware())\n\napp.listen(4433, () =\u003e {\n  console.log('Cool server started at 4433. Try these routes:')\n\n  fooRouter.routes.forEach((route) =\u003e {\n    console.log(`${route.method} http://localhost:4433${route.path}`)\n  })\n})\n```\n\n### [.addResources](index.js#L416)\n\n\u003e Just an alias of [koa-better-router][]'s' `.addRoutes` method.\n\n**Params**\n\n* `...args` **{Array}**: any number of arguments (arrays of route objects)    \n* `returns` **{KoaRestRouter}** `this`: instance for chaining  \n\n### [.getResources](index.js#L454)\n\u003e As we have `.getRoutes` method for getting `this.routes`, so we have `.getResources` for getting `this.resources` array, too. Each `.createResource` returns array of route objects with length of 7, so 7 routes. So if you call `.createResource` two times the `this.resources` (what this method returns) will contain 2 arrays with 7 routes in each of them.\n\n* `returns` **{Array}**: array of arrays of route objects  \n\n**Example**\n\n```js\nlet router = require('koa-rest-router')().loadMethods()\n\nconsole.log(router.routes.length)          // 0\nconsole.log(router.getRoutes().length)     // 0\n\nconsole.log(router.resources.length)       // 0\nconsole.log(router.getResources().length)  // 0\n\nrouter.get('/about', (ctx, next) =\u003e {})\nrouter.resource('dogs')\nrouter.resource('cats')\n\nconsole.log(router.routes.length)          // 15\nconsole.log(router.getRoutes().length)     // 15\n\nconsole.log(router.resources.length)       // 2\nconsole.log(router.getResources().length)  // 2\n```\n\n### [.groupResources](index.js#L521)\n\u003e Powerful method for grouping couple of resources into one resource endpoint. For example you have `/cats` and `/dogs` endpoints, but you wanna create `/cats/:cat/dogs/:dog` endpoint, so you can do such things with that. You can group infinite number of resources. Useful methods that gives you what you should pass as arguments here are `.createResource`, `.createRoute`, `.getResources`, `.getResource` and `.getRoutes`. **Note:** Be aware of that it replaces middlewares of `dest` with the middlewares of last `src`.\n\n**Params**\n\n* `dest` **{Array}**: array of _\"Route Objects\"_ or _\"Resource Object\"_ (both are arrays)    \n* `src1` **{Array}**: array of _\"Route Objects\"_ or _\"Resource Object\"_ (both are arrays)    \n* `src2` **{Array}**: array of _\"Route Objects\"_ or _\"Resource Object\"_ (both are arrays)    \n* `returns` **{Array}**: new array with grouped resources  \n\n**Example**\n\n```js\nlet router = require('koa-rest-router')({ prefix: '/api/v3'})\n\nlet departments = router.createResource('departments')\nlet companies = router.createResource('companies')\nlet profiles = router.createResource('profiles')\nlet clients = router.createResource('clients')\nlet users = router.createResource('users')\nlet cats = router.createResource('cats')\nlet dogs = router.createResource('dogs')\n\n// endpoint: /companies/:company/departments/:department\nlet one = router.groupResources(companies, departments)\n\n// endpoint: /profiles/:profile/clients/:client/cats/:cat\nlet two = router.groupResources(profiles, clients, cats)\n\n// crazy? huh, AWESOME!\n// endpoint: /companies/:company/departments/:department/profiles/:profile/clients/:client/cats/:cat\nlet foo = router.groupResources(one, two)\n\n// but actually just \"register\" `one` and `foo`\n// so you WON'T have `/profiles/:profile/clients/:client/cats/:cat`\n// endpoint in your API\nrouter.addRoutes(one, foo)\n\n// Server part\nlet Koa = require('koa')\nlet app = new Koa()\n\napp.use(router.middleware())\n\napp.listen(4000, () =\u003e {\n  console.log(`Mega API server on http://localhost:4000`)\n  console.log(`Checkout these routes:`)\n\n  // it will output 14 links\n  router.getRoutes().forEach((route) =\u003e {\n    console.log(`${route.method} http://localhost:4000${route.path}`)\n  })\n})\n```\n\n## Related\n- [koa-bel](https://www.npmjs.com/package/koa-bel): View engine for `koa` without any deps, built to be used… [more](https://github.com/tunnckocore/koa-bel#readme) | [homepage](https://github.com/tunnckocore/koa-bel#readme \"View engine for `koa` without any deps, built to be used with `bel`. Any other engines that can be written in `.js` files would work, too.\")\n- [koa-better-body](https://www.npmjs.com/package/koa-better-body): Full-featured [koa][] body parser! Support parsing text, buffer, json, json patch… [more](https://github.com/tunnckocore/koa-better-body#readme) | [homepage](https://github.com/tunnckocore/koa-better-body#readme \"Full-featured [koa][] body parser! Support parsing text, buffer, json, json patch, json api, csp-report, multipart, form and urlencoded bodies. Works for koa@1, koa@2 and will work for koa@3.\")\n- [koa-better-ratelimit](https://www.npmjs.com/package/koa-better-ratelimit): Better, smaller, faster - koa middleware for limit request by ip… [more](https://github.com/tunnckoCore/koa-better-ratelimit) | [homepage](https://github.com/tunnckoCore/koa-better-ratelimit \"Better, smaller, faster - koa middleware for limit request by ip, store in-memory.\")\n- [koa-better-router](https://www.npmjs.com/package/koa-better-router): Stable and lovely router for [koa][], using [path-match][]. Foundation for building… [more](https://github.com/tunnckocore/koa-better-router#readme) | [homepage](https://github.com/tunnckocore/koa-better-router#readme \"Stable and lovely router for [koa][], using [path-match][]. Foundation for building powerful, flexible and RESTful APIs easily.\")\n- [koa-better-serve](https://www.npmjs.com/package/koa-better-serve): Small, simple and correct serving of files, using [koa-send][] - nothing… [more](https://github.com/tunnckocore/koa-better-serve#readme) | [homepage](https://github.com/tunnckocore/koa-better-serve#readme \"Small, simple and correct serving of files, using [koa-send][] - nothing more.\")\n- [koa-ip-filter](https://www.npmjs.com/package/koa-ip-filter): Middleware for [koa][] that filters IPs against glob patterns, RegExp, string… [more](https://github.com/tunnckocore/koa-ip-filter#readme) | [homepage](https://github.com/tunnckocore/koa-ip-filter#readme \"Middleware for [koa][] that filters IPs against glob patterns, RegExp, string or array of globs. Support custom `403 Forbidden` message and custom ID.\")\n- [nanomatch](https://www.npmjs.com/package/nanomatch): Fast, minimal glob matcher for node.js. Similar to micromatch, minimatch and… [more](https://github.com/jonschlinkert/nanomatch) | [homepage](https://github.com/jonschlinkert/nanomatch \"Fast, minimal glob matcher for node.js. Similar to micromatch, minimatch and multimatch, but complete Bash 4.3 wildcard support only (no support for exglobs, posix brackets or braces)\")\n\n## Contributing\nPull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/tunnckoCore/koa-rest-router/issues/new).  \nPlease read the [contributing guidelines](CONTRIBUTING.md) for advice on opening issues, pull requests, and coding standards.  \nIf you need some help and can spent some cash, feel free to [contact me at CodeMentor.io](https://www.codementor.io/tunnckocore?utm_source=github\u0026utm_medium=button\u0026utm_term=tunnckocore\u0026utm_campaign=github) too.\n\n**In short:** If you want to contribute to that project, please follow these things\n\n1. Please DO NOT edit [README.md](README.md), [CHANGELOG.md](CHANGELOG.md) and [.verb.md](.verb.md) files. See [\"Building docs\"](#building-docs) section.\n2. Ensure anything is okey by installing the dependencies and run the tests. See [\"Running tests\"](#running-tests) section.\n3. Always use `npm run commit` to commit changes instead of `git commit`, because it is interactive and user-friendly. It uses [commitizen][] behind the scenes, which follows Conventional Changelog idealogy.\n4. Do NOT bump the version in package.json. For that we use `npm run release`, which is [standard-version][] and follows Conventional Changelog idealogy.\n\nThanks a lot! :)\n\n### Contributing Recipes\nRecipes are just different use cases, written in form of README in human language. Showing some \"Pro Tips\" and tricks, answering common questions and so on. They look like [tests](./test.js), but in more readable and understandable way for humans - mostly for beginners that not reads or understand enough the README or API and tests.\n\n- They are in form of folders in the root [`recipes/`](./recipes) folder: for example `recipes/[short-meaningful-recipe-name]/`.\n- In recipe folder should exist `README.md` file\n- In recipe folder there may have actual js files, too. And should be working.\n- The examples from the recipe README.md should also exist as separate `.js` files.\n- Examples in recipe folder also should be working and actual.\n\nIt would be great if you follow these steps when you want to _fix, update or create_ a recipes. :sunglasses:\n\n- Title for recipe idea should start with `[recipe]`: for example`[recipe] my awesome recipe`\n- Title for new recipe (PR) should also start with `[recipe]`.\n- Titles of Pull Requests or Issues for fixing/updating some existing recipes should start with `[recipe-fix]`.\n\nIt will help a lot, thanks in advance! :yum:\n## Building docs\nDocumentation and that readme is generated using [verb-generate-readme][], which is a [verb][] generator, so you need to install both of them and then run `verb` command like that\n\n```\n$ npm install verbose/verb#dev verb-generate-readme --global \u0026\u0026 verb\n```\n\n_Please don't edit the README directly. Any changes to the readme must be made in [.verb.md](.verb.md)._\n\n## Running tests\nClone repository and run the following in that cloned directory\n\n```\n$ npm install \u0026\u0026 npm test\n```\n\n## Author\n**Charlike Mike Reagent**\n\n+ [github/tunnckoCore](https://github.com/tunnckoCore)\n+ [twitter/tunnckoCore](https://twitter.com/tunnckoCore)\n+ [codementor/tunnckoCore](https://codementor.io/tunnckoCore)\n\n## License\nCopyright © 2016-2017, [Charlike Mike Reagent](https://i.am.charlike.online). Released under the [MIT license](LICENSE).\n\n***\n\n_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.4.1, on February 14, 2017._  \n_Project scaffolded using [charlike][] cli._\n\n[charlike]: https://github.com/tunnckocore/charlike\n[commitizen]: https://github.com/commitizen/cz-cli\n[koa-better-body]: https://github.com/tunnckocore/koa-better-body\n[koa-better-router]: https://github.com/tunnckocore/koa-better-router\n[koa-send]: https://github.com/koajs/send\n[koa]: https://github.com/koajs/koa\n[path-match]: https://github.com/pillarjs/path-match\n[recipe]: https://github.com/DamonOehlman/recipe\n[standard-version]: https://github.com/conventional-changelog/standard-version\n[verb-generate-readme]: https://github.com/verbose/verb-generate-readme\n[verb]: https://github.com/verbose/verb\n\n[downloads-url]: https://www.npmjs.com/package/koa-rest-router\n[downloads-img]: https://img.shields.io/npm/dt/koa-rest-router.svg\n\n[codeclimate-url]: https://codeclimate.com/github/tunnckoCore/koa-rest-router\n[codeclimate-img]: https://img.shields.io/codeclimate/github/tunnckoCore/koa-rest-router.svg\n\n[travis-url]: https://travis-ci.org/olstenlarck/koa-rest-router\n[travis-img]: https://img.shields.io/travis/olstenlarck/koa-rest-router/master.svg?label=linux\n\n[appveyor-url]: https://ci.appveyor.com/project/tunnckoCore/koa-rest-router\n[appveyor-img]: https://img.shields.io/appveyor/ci/tunnckoCore/koa-rest-router/master.svg?label=windows\n\n[coverage-url]: https://codecov.io/gh/olstenlarck/koa-rest-router\n[coverage-img]: https://img.shields.io/codecov/c/github/olstenlarck/koa-rest-router/master.svg\n\n[david-url]: https://david-dm.org/tunnckoCore/koa-rest-router\n[david-img]: https://img.shields.io/david/tunnckoCore/koa-rest-router.svg\n\n[standard-url]: https://github.com/feross/standard\n[standard-img]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg\n\n[gibon]: https://github.com/tunnckocore/gibon\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FtunnckoCore%2Fkoa-rest-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FtunnckoCore%2Fkoa-rest-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FtunnckoCore%2Fkoa-rest-router/lists"}