Project depreciated: This was a fun project but you should use express or fastify for real work.
A hypermodular http server that glues together http, stack and @bret/http-hash-router.
npm i hyperserv
Express is a reliable and widely understood web-framework, but the dream of node.js was framework free network applications. http-framework and substack-flavored-webapp are excellent counterpoints to frameworks like express and hapi but come along with a pile of boilerplate. hyperserv aims to glue together the basics of any web server by providing a routing layer and a middleware layer to offer up a quick way to write small webservers the hypermodular way (or, more specifically, one hypermodular way)!
How you launch and configure your webservers seems to be a deeply personal ceremony. hyperserv leaves this up to you and just puts together the webserver for you.
var minimist = require('minimist')
var morgan = require('morgan')
var Hyperserv = require('hyperserv')
var app = new Hyperserv()
var argv = minimist(process.argv.slice(2), {
alias: { p: 'port' },
default: { port: 8000 }
})
var ecstatic = require('ecstatic')
var path = require('path')
process.title = 'hyperserv'
// Reconfigure the middlewre stack sitting in front of the routes.
app.composeStack([
morgan('dev')
])
var staticPath = path.join(__dirname, 'static')
console.log(staticPath)
app.router.set('/static', ecstatic({
root: staticPath,
baseDir: 'static',
handleError: false
}))
// Set up routes
app.router.set('/', function (req, res, opts, cb) {
res.end('hi')
})
// Set up routes
app.router.set('/:name', function (req, res, opts, cb) {
res.end('hello ' + opts.params.name)
})
// Routes can fly fast and loose. It don't matter
app.router.set('/crash', function (req, res, opts, cb) {
throw new Error('This route crashed intentionally')
})
function expressMiddleware (req, res, next) {
res.write(JSON.stringify(req.opts) + '\n')
res.end('this is an express/connect style middleware layer')
}
app.router.set('/:name/express', expressMiddleware)
app.httpServer.listen(argv.port)
Hyperserv now supports connect style routes out of the box. The opts
object that holds params and app level vars are now extended into the req.opts
object by default, when the route doesn't accept an opts
argument.
Returns a new hyperserv app
object. It sets up an httpServer that has a middleware handler and router.
Default options:
{
layers: [ require('morgan')('dev') ],
sendTraces: true,
logTraces: true,
logDetails: true
}
layers
: Provide an array of middleware functions (function layer (req, res, cb) {}
) that get stuck in front of the final routing layer. You can reconfigure this layer at any point withserver.composeStack
.sendTraces
: Specify if stack traces are sent in theres
if thereq
runs into any kind of error. Defaults tofalse
logTraces
: Attach the default error handler to theerror
event emitted from the server whenever it encounters an error.
function errorHandler (err) {
if (err.statusCode !== 404) console.log(err)
}
logDetails
: Attach the default server start log message to the server to fire when it starts listening.
This is an instance of http.createServer
. It isn't started yet, so set up your event handlers, and turn it on with app.httpServer.listen(port)
This is the @bret/http-hash-router
router object that has simply been attached to the http
server instance. Read all about it here:
This sets a route and a route handler. Remember, routeHandlers expect the following signature function route (req, res, opts, cb) {}
. You can compose middleware stack's to plop inside of route handlers using stack.compose
.
See bcomnes/http-hash-router#example
This lets you pass an array of middleware layers (function layer (req, res, cb) {}
) to stick in front of the http-hash-router
layer. You can do body parsing, cookie parsing, sessions, and auth stuff here. Calling composeStack
tosses the existing middleware stack out in favor of the one you pass in here.
This is the default error handler that gets passed to the server's error
event when logTraces
is set to true when creating a server
. It is an instance method that you can reassign if you want.
function errorHandler (err) {
if (err.statusCode !== 404) console.log(err)
}
If you want to use it as is with the server, use the logTraces
option. It is exported only for convince and access and should not be normally used directly.
This is the default logging function that runs when the server starts listening. Use the logDetails
options to turn it on or off. It is an instance method that you can reassign if you want.
Pass in a connect style middleware layer and get back a http-hash-router
route handler. The returned route handler mixes in any options it receives on its opts
argument to req.opts
.
function makeRoute (layer) {
return (req, res, opts, cb) => {
req.opts = extend(req.opts, opts)
layer(req, res, cb)
}
}