{"_id":"@auctumnus/polka","_rev":"1-f40eddb5a40209da4c3bf047dc6c5846","name":"@auctumnus/polka","dist-tags":{"latest":"1.0.0-next.22"},"versions":{"1.0.0-next.22":{"name":"@auctumnus/polka","version":"1.0.0-next.22","repository":{"type":"git","url":"git+https://github.com/auctumnus/polka.git"},"description":"A micro web server so fast, it'll make you dance! :dancers:","module":"build.mjs","types":"index.d.ts","main":"build.js","license":"MIT","exports":{".":{"import":"./build.mjs","require":"./build.js"},"./package.json":"./package.json"},"author":{"name":"Luke Edwards","email":"luke@lukeed.com","url":"https://lukeed.com"},"engines":{"node":">=8"},"dependencies":{"@polka/url":"^1.0.0-next.21","trouter":"^3.1.0"},"gitHead":"8a3af42b46659d0ab02816f02e854ff1c39e7455","bugs":{"url":"https://github.com/auctumnus/polka/issues"},"homepage":"https://github.com/auctumnus/polka#readme","_id":"@auctumnus/polka@1.0.0-next.22","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-LEYbz2VTKTWgfQaDNvReRtQGpgvF9DVe9oZV4q50BMoKeDiavxzs3aHTtNxhrBEBOErNz59cFxfgWwXT7dpRIg==","shasum":"18014cd94f3ead15dbb28d9a3b1d29c6c40b2087","tarball":"https://registry.npmjs.org/@auctumnus/polka/-/polka-1.0.0-next.22.tgz","fileCount":3,"unpackedSize":24972,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhms97CRA9TVsSAnZWagAAaZ4P/icgywU8O7wWJOXkLyB1\nSFu9nOC/eF5mfuwRjHRtVzS5uIb0V1dSVO12oCkuN8SMjiJESWQjMUVTaj2c\n+qJkLkZKd7cxDzTefzDUiQyIZxN44C6TkwyzpEavVKp9iFEGUxjWGHnXgEsM\nz0KJZSh594pCBymM3auEniS6pnIoC6GohKL9wUiFum1+EJICDW7yOfRVfPmA\nSVvqVw6d2JuVN92T/vJdWtyMbkzosk8/tRr/mWY6NgpkhEb7e5diUycZxcu3\nwGvedzf4Hp7BkLIz1Z6pNAYhIyRTOIllAFYMVQM4in4ExI7RVPr3u/RCZnQu\nC0JubFf+EI4oVDFP54xavsgQJKxe4DtrxWzHDtP0Hg+5rjmbqJwoONrsSNy2\n46I34JCdSaSFtssY6xJQ6WJsFluNjyHDAMn3pFo9z/A2NaT175M91Z1FGrRo\n+W8YBeO26iKnaE6DV3bMyfHdDY2wtCRzGm8C+/gP+ksFJrKRwV5XPgxzNa5Z\ncXVMVdLY/YBQUJ17LopM7X4bVlW1s8spKWIEYpQbmeXPXNVe4uXpcigvRsLy\ng8NFtnr6wRc5JJgFcKeGhmOqM7l6H56xYi1x4Oi3pyjSvsag7IP4mKE4ogwQ\nGfO5QRgtOBNXCe4P0O0rGhmHQZ1FCrVb1mS14o+EGSCJfKRDKvg8HN46jp9R\nvDsg\r\n=yx+z\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDf8her/9RKMEfsU1nX9gQc5VzEjNHgg6CPmHAuJdJ3FAiEA6b129+WGO9Qy8/4bmTBXN94hAnxe1Gh5qKbJ21vlfOI="}]},"_npmUser":{"name":"auctumnus","email":"auctumnus@pm.me"},"directories":{},"maintainers":[{"name":"auctumnus","email":"auctumnus@pm.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/polka_1.0.0-next.22_1637535610866_0.44662935316361185"},"_hasShrinkwrap":false}},"time":{"created":"2021-11-21T23:00:10.808Z","1.0.0-next.22":"2021-11-21T23:00:11.070Z","modified":"2022-04-04T16:22:11.836Z"},"maintainers":[{"name":"auctumnus","email":"auctumnus@pm.me"}],"description":"A micro web server so fast, it'll make you dance! :dancers:","homepage":"https://github.com/auctumnus/polka#readme","repository":{"type":"git","url":"git+https://github.com/auctumnus/polka.git"},"author":{"name":"Luke Edwards","email":"luke@lukeed.com","url":"https://lukeed.com"},"bugs":{"url":"https://github.com/auctumnus/polka/issues"},"license":"MIT","readme":"<div align=\"center\">\n  <img src=\"https://github.com/lukeed/polka/raw/master/polka.png\" alt=\"Polka\" width=\"400\" height=\"300\" />\n</div>\n\n<h1 align=\"center\">Polka</h1>\n\n<div align=\"center\">\n  <a href=\"https://npmjs.org/package/polka\">\n    <img src=\"https://badgen.now.sh/npm/v/polka\" alt=\"version\" />\n  </a>\n  <a href=\"https://travis-ci.org/lukeed/polka\">\n    <img src=\"https://badgen.now.sh/travis/lukeed/polka\" alt=\"travis\" />\n  </a>\n  <a href=\"https://codecov.io/gh/lukeed/polka\">\n    <img src=\"https://badgen.now.sh/codecov/c/github/lukeed/polka\" alt=\"codecov\" />\n  </a>\n  <a href=\"https://npmjs.org/package/polka\">\n    <img src=\"https://badgen.now.sh/npm/dm/polka\" alt=\"downloads\" />\n  </a>\n  <a href=\"https://packagephobia.now.sh/result?p=polka\">\n    <img src=\"https://packagephobia.now.sh/badge?p=polka\" alt=\"install size\" />\n  </a>\n</div>\n\n<div align=\"center\">A micro web server so fast, it'll make you dance! :dancers:</div>\n\n<br />\n\nPolka is an extremely minimal, highly performant Express.js alternative. Yes, you're right, Express is _already_ super fast & not _that_ big :thinking: &mdash; but Polka shows that there was (somehow) room for improvement!\n\nEssentially, Polka is just a [native HTTP server](https://nodejs.org/dist/latest-v9.x/docs/api/http.html#http_class_http_server) with added support for routing, middleware, and sub-applications. That's it! :tada:\n\nAnd, of course, in mandatory bullet-point format:\n\n* 33-50% faster than Express for simple applications\n* Middleware support, including Express middleware you already know & love\n* Nearly identical application API & route pattern definitions\n* ~90 LOC for Polka, 120 including [its router](https://github.com/lukeed/trouter)\n\n\n## Install\n\n```\n$ npm install --save polka\n```\n\n## Usage\n\n```js\nconst polka = require('polka');\n\nfunction one(req, res, next) {\n  req.hello = 'world';\n  next();\n}\n\nfunction two(req, res, next) {\n  req.foo = '...needs better demo 😔';\n  next();\n}\n\npolka()\n  .use(one, two)\n  .get('/users/:id', (req, res) => {\n    console.log(`~> Hello, ${req.hello}`);\n    res.end(`User: ${req.params.id}`);\n  })\n  .listen(3000, () => {\n    console.log(`> Running on localhost:3000`);\n  });\n```\n\n## API\n\nPolka extends [Trouter](https://github.com/lukeed/trouter) which means it inherits its API, too!\n\n### polka(options)\n\nReturns an instance of Polka~!\n\n#### options.server\nType: `Server`<br>\n\nA custom, instantiated server that the Polka instance should attach its [`handler`](#handlerreq-res-parsed) to. This is useful if you have initialized a server elsewhere in your application and want Polka to use _it_ instead of creating a new `http.Server`.\n\nPolka _only_ updates the server when [`polka.listen`](#listen) is called. At this time, Polka will create a [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server) if a server was not already provided via `options.server`.\n\n> **Important:** The `server` key will be `undefined` until `polka.listen` is invoked, unless a server was provided.\n\n#### options.onError\nType: `Function`\n\nA catch-all error handler; executed whenever a middleware throws an error. Change this if you don't like default behavior.\n\nIts signature is `(err, req, res, next)`, where `err` is the `String` or `Error` thrown by your middleware.\n\n> **Caution:** Use `next()` to bypass certain errors **at your own risk!** <br>You must be certain that the exception will be handled elsewhere or _can_ be safely ignored. <br>Otherwise your response will never terminate!\n\n#### options.onNoMatch\nType: `Function`\n\nA handler when no route definitions were matched. Change this if you don't like default behavior, which sends a `404` status & `Not found` response.\n\nIts signature is `(req, res)` and requires that you terminate the response.\n\n\n### use(base, ...fn)\n\nAttach [middleware(s)](#middleware) and/or sub-application(s) to the server. These will execute _before_ your routes' [handlers](#handlers).\n\n**Important:** If a `base` pathname is provided, all functions within the same `use()` block will _only_ execute when the `req.path` matches the `base` path.\n\n#### base\nType: `String`<br>\nDefault: `undefined`\n\nThe base path on which the following middleware(s) or sub-application should be mounted.\n\n#### fn\nType: `Function|Array`\n\nYou may pass one or more functions at a time. Each function must have the standardized `(req, res, next)` signature.\n\nYou may also pass a sub-application, which _must_ be accompanied by a `base` pathname.\n\nPlease see [`Middleware`](#middleware) and [Express' middleware examples](http://expressjs.com/en/4x/api.html#middleware-callback-function-examples) for more info.\n\n\n### parse(req)\n\nReturns: `Object` or `undefined`\n\nAs of `v0.5.0`, this is an alias of the [`@polka/url`](/packages/url) module. For nearly all cases, you'll notice no changes.\n\nBut, for whatever reason, you can quickly swap in [`parseurl`](https://github.com/pillarjs/parseurl) again:\n\n```js\nconst app = polka();\napp.parse = require('parseurl');\n//=> Done!\n```\n\n### listen()\n\nReturns: `Polka`\n\nBoots (or creates) the underlying [`http.Server`](https://nodejs.org/dist/latest-v9.x/docs/api/http.html#http_class_http_server) for the first time. All arguments are passed to [`server.listen`](https://nodejs.org/dist/latest-v9.x/docs/api/net.html#net_server_listen) directly with no changes.\n\nAs of `v0.5.0`, this method no longer returns a Promise. Instead, the current Polka instance is returned directly, allowing for chained operations.\n\n```js\n// Could not do this before 0.5.0\nconst { server, handler } = polka().listen();\n\n// Or this!\nconst app = polka().listen(PORT, onAppStart);\n\napp.use('users', require('./users'))\n  .get('/', (req, res) => {\n    res.end('Pretty cool!');\n  });\n```\n\n### handler(req, res, parsed)\n\nThe main Polka [`IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) handler. It receives all requests and tries to match the incoming URL against known routes.\n\nIf the `req.url` is not immediately matched, Polka will look for sub-applications or middleware groups matching the `req.url`'s [`base`](#base) path. If any are found, they are appended to the loop, running _after_ any global middleware.\n\n> **Note:** Any middleware defined within a sub-application is run _after_ the main app's (aka, global) middleware and _before_ the sub-application's route handler.\n\nAt the end of the loop, if a middleware hasn't yet terminated the response (or thrown an error), the route handler will be executed, if found &mdash; otherwise a `(404) Not found` response is returned, configurable via [`options.onNoMatch`](#optionsonnomatch).\n\n#### req\nType: `IncomingMessage`\n\n#### res\nType: `ServerResponse`\n\n#### parsed\nType: `Object`\n\nOptionally provide a parsed [URL](https://nodejs.org/dist/latest-v9.x/docs/api/url.html#url_class_url) object. Useful if you've already parsed the incoming path. Otherwise, [`app.parse`](#parsereq) (aka [`parseurl`](https://github.com/pillarjs/parseurl)) will run by default.\n\n\n## Routing\n\nRoutes are used to define how an application responds to varying HTTP methods and endpoints.\n\n> If you're coming from Express, there's nothing new here!<br> However, do check out [Comparisons](#comparisons) for some pattern changes.\n\n### Basics\n\nEach route is comprised of a [path pattern](#patterns), a [HTTP method](#methods), and a [handler](#handlers) (aka, what you want to do).\n\nIn code, this looks like:\n\n```js\napp.METHOD(pattern, handler);\n```\n\nwherein:\n\n* `app` is an instance of `polka`\n* [`METHOD`](#methods) is any valid HTTP/1.1 method, lowercased\n* [`pattern`](#patterns) is a routing pattern (string)\n* [`handler`](#handlers) is the function to execute when `pattern` is matched\n\nAlso, a single pathname (or `pattern`) may be reused with multiple METHODs.\n\nThe following example demonstrates some simple routes.\n\n```js\nconst app = polka();\n\napp.get('/', (req, res) => {\n  res.end('Hello world!');\n});\n\napp.get('/users', (req, res) => {\n  res.end('Get all users!');\n});\n\napp.post('/users', (req, res) => {\n  res.end('Create a new User!');\n});\n\napp.put('/users/:id', (req, res) => {\n  res.end(`Update User with ID of ${req.params.id}`);\n});\n\napp.delete('/users/:id', (req, res) => {\n  res.end(`CY@ User ${req.params.id}!`);\n});\n```\n\n### Patterns\n\nUnlike the very popular [`path-to-regexp`](https://github.com/pillarjs/path-to-regexp), Polka uses string comparison to locate route matches. While [faster](https://github.com/lukeed/matchit#benchmarks) & more memory efficient, this does also prevent complex pattern matching.\n\nHowever, have no fear! :boom: All the basic and most commonly used patterns are supported. You probably only ever used these patterns in the first place. :wink:\n\n> See [Comparisons](#comparisons) for the list of `RegExp`-based patterns that Polka does not support.\n\nThe supported pattern types are:\n\n* static (`/users`)\n* named parameters (`/users/:id`)\n* nested parameters (`/users/:id/books/:title`)\n* optional parameters (`/users/:id?/books/:title?`)\n* any match / wildcards (`/users/*`)\n\n### Parameters\n\nAny named parameters included within your route [`pattern`](#patterns) will be automatically added to your incoming `req` object. All parameters will be found within `req.params` under the same name they were given.\n\n> **Important:** Your parameter names should be unique, as shared names will overwrite each other!\n\n```js\napp.get('/users/:id/books/:title', (req, res) => {\n  let { id, title } = req.params;\n  res.end(`User: ${id} && Book: ${title}`);\n});\n```\n\n```sh\n$ curl /users/123/books/Narnia\n#=> User: 123 && Book: Narnia\n```\n\n### Methods\n\nAny valid HTTP/1.1 method is supported! However, only the most common methods are used throughout this documentation for demo purposes.\n\n> **Note:** For a full list of valid METHODs, please see [this list](https://github.com/lukeed/trouter#method).\n\n### Handlers\n\nRequest handlers accept the incoming [`IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage) and the formulating [`ServerResponse`](https://nodejs.org/dist/latest-v9.x/docs/api/http.html#http_class_http_serverresponse).\n\nEvery route definition must contain a valid `handler` function, or else an error will be thrown at runtime.\n\n> **Important:** You must _always_ terminate a `ServerResponse`!\n\nIt's a **very good** practice to _always_ terminate your response ([`res.end`](https://nodejs.org/api/http.html#http_request_end_data_encoding_callback)) inside a handler, even if you expect a [middleware](#middleware) to do it for you. In the event a response is/was not terminated, the server will hang & eventually exit with a `TIMEOUT` error.\n\n> **Note:** This is a native `http` behavior.\n\n#### Async Handlers\n\nIf using Node 7.4 or later, you may leverage native `async` and `await` syntax! :heart_eyes_cat:\n\nNo special preparation is needed &mdash; simply add the appropriate keywords.\n\n```js\nconst app = polka();\n\nconst sleep = ms => new Promise(r => setTimeout(r, ms));\n\nasync function authenticate(req, res, next) {\n  let token = req.headers['authorization'];\n  if (!token) return (res.statusCode=401,res.end('No token!'));\n  req.user = await Users.find(token); // <== fake\n  next(); // done, woot!\n}\n\napp\n  .use(authenticate)\n  .get('/', async (req, res) => {\n    // log middleware's findings\n    console.log('~> current user', req.user);\n    // force sleep, because we can~!\n    await sleep(500);\n    // send greeting\n    res.end(`Hello, ${req.user.name}`);\n  });\n```\n\n\n## Middleware\n\nMiddleware are functions that run in between (hence \"middle\") receiving the request & executing your route's [`handler`](#handlers) response.\n\n> Coming from Express? Use any middleware you already know & love! :tada:\n\nThe middleware signature receives the request (`req`), the response (`res`), and a callback (`next`).\n\nThese can apply mutations to the `req` and `res` objects, and unlike Express, have access to `req.params`, `req.path`, `req.search`, and `req.query`!\n\nMost importantly, a middleware ***must*** either call `next()` or terminate the response (`res.end`). Failure to do this will result in a never-ending response, which will eventually crash the `http.Server`.\n\n```js\n// Log every request\nfunction logger(req, res, next) {\n  console.log(`~> Received ${req.method} on ${req.url}`);\n  next(); // move on\n}\n\nfunction authorize(req, res, next) {\n  // mutate req; available later\n  req.token = req.headers['authorization'];\n  req.token ? next() : ((res.statusCode=401) && res.end('No token!'));\n}\n\npolka().use(logger, authorize).get('*', (req, res) => {\n  console.log(`~> user token: ${req.token}`);\n  res.end('Hello, valid user');\n});\n```\n\n```sh\n$ curl /\n# ~> Received GET on /\n#=> (401) No token!\n\n$ curl -H \"authorization: secret\" /foobar\n# ~> Received GET on /foobar\n# ~> user token: secret\n#=> (200) Hello, valid user\n```\n\n### Middleware Sequence\n\nIn Polka, middleware functions are organized into tiers.\n\nUnlike Express, Polka middleware are tiered into \"global\", \"filtered\", and \"route-specific\" groups.\n\n* Global middleware are defined via `.use('/', ...fn)` or `.use(...fn)`, which are synonymous.<br>_Because_ every request's `pathname` begins with a `/`, this tier is always triggered.\n\n* Sub-group or \"filtered\" middleware are defined with a base `pathname` that's more specific than `'/'`. For example, defining `.use('/users', ...fn)` will run on any `/users/**/*` request.<br>These functions will execute _after_ \"global\" middleware but before the route-specific handler.\n\n* Route handlers match specific paths and execute last in the chain. They must also match the `method` action.\n\nOnce the chain of middleware handler(s) has been composed, Polka will iterate through them sequentially until all functions have run, until a chain member has terminated the response early, or until a chain member has thrown an error.\n\nContrast this with Express, which does not tier your middleware and instead iterates through your entire application in the sequence that you composed it.\n\n```js\n// Express\nexpress()\n  .get('/', get)\n  .use(foo)\n  .get('/users/123', user)\n  .use('/users', users)\n\n// Polka\nPolka()\n  .get('/', get)\n  .use(foo)\n  .get('/users/123', user)\n  .use('/users', users)\n```\n\n```sh\n$ curl {APP}/\n# Express :: [get]\n# Polka   :: [foo, get]\n\n$ curl {APP}/users/123\n# Express :: [foo, user]\n# Polka   :: [foo, users, user]\n```\n\n\n### Middleware Errors\n\nIf an error arises within a middleware, the loop will be exited. This means that no other middleware will execute & neither will the route handler.\n\nSimilarly, regardless of `statusCode`, an early response termination will also exit the loop & prevent the route handler from running.\n\nThere are three ways to \"throw\" an error from within a middleware function.\n\n> **Hint:** None of them use `throw` :joy_cat:\n\n1. **Pass any string to `next()`**\n\n    This will exit the loop & send a `500` status code, with your error string as the response body.\n\n    ```js\n    polka()\n      .use((req, res, next) => next('💩'))\n      .get('*', (req, res) => res.end('wont run'));\n    ```\n\n    ```sh\n    $ curl /\n    #=> (500) 💩\n    ```\n\n2. **Pass an `Error` to `next()`**\n\n    This is similar to the above option, but gives you a window in changing the `statusCode` to something other than the `500` default.\n\n    ```js\n    function oopsies(req, res, next) {\n      let err = new Error('Try again');\n      err.code = 422;\n      next(err);\n    }\n    ```\n\n    ```sh\n    $ curl /\n    #=> (422) Try again\n    ```\n\n3. **Terminate the response early**\n\n    Once the response has been ended, there's no reason to continue the loop!\n\n    This approach is the most versatile as it allows to control every aspect of the outgoing `res`.\n\n    ```js\n    function oopsies(req, res, next) {\n      if (true) {\n        // something bad happened~\n        res.writeHead(400, {\n          'Content-Type': 'application/json',\n          'X-Error-Code': 'Please dont do this IRL'\n        });\n        let json = JSON.stringify({ error:'Missing CSRF token' });\n        res.end(json);\n      } else {\n        next(); // never called FYI\n      }\n    }\n    ```\n\n    ```sh\n    $ curl /\n    #=> (400) {\"error\":\"Missing CSRF token\"}\n    ```\n\n\n## Benchmarks\n\nQuick comparison between various frameworks using [`wrk`](https://github.com/wg/wrk) on `Node v10.4.0`.<br> Results are taken with the following command, after one warm-up run:\n\n```\n$ wrk -t4 -c4 -d10s http://localhost:3000/users/123\n```\n\nAdditional benchmarks between Polka and Express (using various Node versions) can be [found here](/bench).\n\n> **Important:** Time is mostly spent in _your application code_ rather than Express or Polka code!<br> Switching from Express to Polka will (likely) not show such drastic performance gains.\n\n```\nNative\n    Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     1.91ms  110.95us   5.54ms   93.08%\n        Req/Sec    13.11k   308.16    13.46k    94.31%\n      526992 requests in 10.10s, 52.27MB read\n    Requests/sec:  52177.09\n    Transfer/sec:      5.18MB\n\nPolka\n    Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     1.97ms  103.56us   4.63ms   92.30%\n        Req/Sec    12.76k   172.50    13.13k    85.75%\n      507836 requests in 10.00s, 50.37MB read\n    Requests/sec:  50779.77\n    Transfer/sec:      5.04MB\n\nRayo\n    Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     2.02ms  116.55us   6.66ms   92.55%\n        Req/Sec    12.43k   262.32    12.81k    91.58%\n      499795 requests in 10.10s, 49.57MB read\n    Requests/sec:  49481.55\n    Transfer/sec:      4.91MB\n\nFastify\n    Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     2.10ms  138.04us   5.46ms   91.50%\n        Req/Sec    11.96k   414.14    15.82k    95.04%\n      479518 requests in 10.10s, 66.31MB read\n    Requests/sec:  47476.75\n    Transfer/sec:      6.57MB\n\nKoa\n    Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     2.95ms  247.10us   6.91ms   72.18%\n        Req/Sec     8.52k   277.12     9.09k    70.30%\n      342518 requests in 10.10s, 47.36MB read\n    Requests/sec:  33909.82\n    Transfer/sec:      4.69MB\n\nExpress\n    Thread Stats   Avg      Stdev     Max   +/- Stdev\n        Latency     4.91ms  484.52us  10.65ms   89.71%\n        Req/Sec     5.11k   350.75     9.69k    98.51%\n      204520 requests in 10.10s, 40.57MB read\n    Requests/sec:  20249.80\n    Transfer/sec:      4.02MB\n```\n\n\n## Comparisons\n\nPolka's API aims to be _very_ similar to Express since most Node.js developers are already familiar with it. If you know Express, you already know Polka! :dancer:\n\nThere are, however, a few main differences. Polka does not support or offer:\n\n1) **Polka uses a tiered middleware system.**\n\n    Express maintains the sequence of your route & middleware declarations during its runtime, which can pose a problem when composing sub-applications. Typically, this forces you to duplicate groups of logic.\n\n    Please see [Middleware Sequence](#middleware-sequence) for an example and additional details.\n\n2) **Any built-in view/rendering engines.**\n\n    Most templating engines can be incorporated into middleware functions or used directly within a route handler.\n\n3) **The ability to `throw` from within middleware.**\n\n    However, all other forms of middleware-errors are supported. (See [Middleware Errors](#middleware-errors).)\n\n    ```js\n    function middleware(res, res, next) {\n      // pass an error message to next()\n      next('uh oh');\n\n      // pass an Error to next()\n      next(new Error('🙀'));\n\n      // send an early, customized error response\n      res.statusCode = 401;\n      res.end('Who are you?');\n    }\n    ```\n\n4) **Express-like response helpers... yet! (#14)**\n\n    Express has a nice set of [response helpers](http://expressjs.com/en/4x/api.html#res.append). While Polka relies on the [native Node.js response methods](https://nodejs.org/dist/latest-v9.x/docs/api/http.html#http_class_http_serverresponse), it would be very easy/possible to attach a global middleware that contained a similar set of helpers. (_TODO_)\n\n5) **`RegExp`-based route patterns.**\n\n    Polka's router uses string comparison to match paths against patterns. It's a lot quicker & more efficient.\n\n    The following routing patterns **are not** supported:\n\n    ```js\n    app.get('/ab?cd', _ => {});\n    app.get('/ab+cd', _ => {});\n    app.get('/ab*cd', _ => {});\n    app.get('/ab(cd)?e', _ => {});\n    app.get(/a/, _ => {});\n    app.get(/.*fly$/, _ => {});\n    ```\n\n    The following routing patterns **are** supported:\n\n    ```js\n    app.get('/users', _ => {});\n    app.get('/users/:id', _ => {});\n    app.get('/users/:id?', _ => {});\n    app.get('/users/:id/books/:title', _ => {});\n    app.get('/users/*', _ => {});\n    ```\n\n6) **Polka instances are not (directly) the request handler.**\n\n    Most packages in the Express ecosystem expect you to pass your `app` directly into the package. This is because `express()` returns a middleware signature directly.\n\n    In the Polka-sphere, this functionality lives in your application's [`handler`](#handlerreq-res-parsed) instead.\n\n    Here's an example with [`supertest`](https://github.com/visionmedia/supertest), a popular testing utility for Express apps.\n\n    ```js\n    const request = require('supertest');\n    const send = require('@polka/send-type');\n\n    const express = require('express')();\n    const polka = require('polka')();\n\n    express.get('/user', (req, res) => {\n      res.status(200).json({ name: 'john' });\n    });\n\n    polka.get('/user', (req, res) => {\n      send(res, 200, { name: 'john' });\n    });\n\n    function isExpected(app) {\n      request(app)\n        .get('/user')\n        .expect('Content-Type', /json/)\n        .expect('Content-Length', '15')\n        .expect(200);\n    }\n\n    // Express: Pass in the entire application directly\n    isExpected(express);\n\n    // Polka: Pass in the application `handler` instead\n    isExpected(polka.handler);\n    ```\n\n\n## License\n\nMIT © [Luke Edwards](https://lukeed.com)\n","readmeFilename":"readme.md"}