Verified Commit 52f31236 authored by Aral Balkan's avatar Aral Balkan
Browse files

Implement feature: dynamic routes

parent cc6042e3
......@@ -8,6 +8,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Nothing yet.
## [10.2.0] - 2019-05-14
## Added
- Dynamic routes feature. You can now specify simple dynamic routes by including middleware functions in JS files within a folder named _.routes_ in your web folder.
## [10.1.0] - 2019-05-14
### Added
......
......@@ -328,6 +328,33 @@ If you do not create custom error pages, the built-in default error pages will b
When creating your own servers (see [API](#API)), you can generate the default error pages programmatically using the static methods `WebServer.default404ErrorPage()` and `WebServer.default500ErrorPage()`, passing in the missing path and the error message as the argument, respectively to get the HTML string of the error page returned.
## Dynamic routes
You can include very basic dynamic routes by including JavaScript files that export middleware-style functions in a special _.routes_ folder in the root folder of your web content. The syntax and conventions are [detailed here](https://source.ind.ie/hypha/tools/web-routes-from-files).
So, for example, if you wanted to have a dynamic route that showed the server CPU load and free memory, you could create a file called _.routes/server-stats.js_ in your web folder with the following content:
```js
const os = require('os')
function serverStats (request, response, next) {
const loadAverages = `<p> ${os.loadavg().reduce((a, c, i) => `${a}\n<li><strong>CPU ${i+1}:</strong> ${c}</li>`, '<ul>') + '</ul>'}</p>`
const freeMemory = `<p>${os.freemem()} bytes</p>`
const page = `<html><head><title>Server statistics</title><style>body {font-family: sans-serif;}</style></head><body><h1>Server statistics</h1><h2>Load averages</h2>${loadAverages}<h2>Free memory</h2>${freeMemory}</body></html>`
response.end(page)
}
module.exports = serverStats
```
Indie Web Server will load your dynamic route at startup and you can test it by hitting _https://localhost/server-stats_ using a local web server. Each time you refresh, you should get the latest dynamic content.
__Note:__ You shouldn’t use this functionality to create your latest amazing web app. To do that, include Indie Web Server as a node module in your project and extend it that way. This is to add tiny bits of dynamic functionality. The routes are added as `get` routes and the only Node modules you will have access to are the ones used by Indie Web Server. Again, if you need custom modules, extend Indie Web Server using Node.js.
## API
Indie Web Server’s `createServer` method behaves like the built-in _https_ module’s `createServer` function. Anywhere you use `require('https').createServer`, you can simply replace it with `require('@ind.ie/web-server').createServer`.
......
......@@ -14,6 +14,7 @@ const Graceful = require('node-graceful')
const AcmeTLS = require('@ind.ie/acme-tls')
const nodecert = require('@ind.ie/nodecert')
const getRoutes = require('@ind.ie/web-routes-from-files')
const ensure = require('./bin/lib/ensure')
......@@ -207,6 +208,17 @@ class WebServer {
}
})
// Add dynamic routes, if they have been specified in <pathToServer>.routes/name-of-route.js
const dynamicRoutesDirectory = path.join(pathToServe, '.routes')
if (fs.existsSync(dynamicRoutesDirectory)) {
const dynamicRoutes = getRoutes(dynamicRoutesDirectory)
dynamicRoutes.forEach(route => {
console.log(` 🐁 Dynamic route loaded: ${route.path}\n`)
app.get(route.path, require(route.callback))
})
}
app.use(express.static(pathToServe))
// Serve the archive cascade (if there is one).
......
{
"name": "@ind.ie/web-server",
"version": "10.0.1",
"version": "10.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
......@@ -183,6 +183,11 @@
"resolved": "https://registry.npmjs.org/@ind.ie/rsa-compat/-/rsa-compat-1.0.0.tgz",
"integrity": "sha512-6v4Mh1vqoXgLhYESG3PvOp29EclvfdLEAgwnDdVNzW8rVuFoD+ZaNTSqdPQKTYUO5+9/03GQxEtzgF5v5M6C+w=="
},
"@ind.ie/web-routes-from-files": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@ind.ie/web-routes-from-files/-/web-routes-from-files-1.0.0.tgz",
"integrity": "sha512-9/8PvK1cj83dtb510yFKSVh0Pi08ES6D6iTnCNuYSf8YU9C++inumNlrbN+E9KxjPM69xsRqnHvKqDdrPZy3vw=="
},
"@mrmlnc/readdir-enhanced": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
......
{
"name": "@ind.ie/web-server",
"version": "10.1.0",
"version": "10.2.0",
"description": "A secure and seamless Small Tech personal web server.",
"main": "index.js",
"bin": "bin/web-server.js",
......@@ -25,6 +25,7 @@
"dependencies": {
"@ind.ie/acme-tls": "^2.1.2",
"@ind.ie/nodecert": "^3.0.1",
"@ind.ie/web-routes-from-files": "^1.0.0",
"ansi-escape-sequences": "^4.1.0",
"chokidar": "^2.1.5",
"copy-concurrently": "^1.0.5",
......
const os = require('os')
function serverStats (request, response, next) {
const loadAverages = `<p> ${os.loadavg().reduce((a, c, i) => `${a}\n<li><strong>CPU ${i+1}:</strong> ${c}</li>`, '<ul>') + '</ul>'}</p>`
const freeMemory = `<p>${os.freemem()} bytes</p>`
const page = `<html><head><title>Server statistics</title><style>body {font-family: sans-serif;}</style></head><body><h1>Server statistics</h1><h2>Load averages</h2>${loadAverages}<h2>Free memory</h2>${freeMemory}</body></html>`
response.end(page)
}
module.exports = serverStats
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment