HTTP the web framework – @Raynos – The origins



HTTP the web framework – @Raynos – The origins

0 0


jsfest2014-talk

HTTP the web framework

On Github Raynos / jsfest2014-talk

Elapsed

00m

HTTP the web framework

@Raynos

require('http') is all you need

Because of `npm`, we no longer need off the shelf web frameworks

The origins

Fed up with `express`. It's bad, but that's for another talk

The origins

Wanting a better approach, finding inspiration in `isaacs/npm-www` and `mikeal/tako`.

The origins

Lessons from `isaac/npm-www`

  • No frameworks, only modules
  • No MVC, just routes
  • Req/res helpers are small functions
  • `express` is a glorified router

The origins

Lessons from `mikeal/tako`

  • Frameworks are glorified routers
  • Application wide 404/500 pages
  • Templates/views are complex

The experiment

`Raynos/routil`, the underscore of `http`

The experiment

Lessons learned

  • Makes collaboration difficult
  • Makes mixing and matching difficult
  • Hard to deprecate subsets
  • Coupling gives no advantages

The modules

publishing to `npm` is easy. Thus modules are born

The modules

var sendJson = require('send-data/json')
var db = require('./db.js')

// GET /users/:id
module.exports = function* getUser(req, res, opts) {
  var user = yield db.users.get.bind(db.users, opts.id)

  sendJson(req, res, user)
}

The modules

var jsonBody = require('body/json')
var db = require('./db.js')

// PUT /users/:id
module.exports = function* saveUser(req, res, opts) {
  var body = yield jsonBody.bind(null, req, res)

  yield db.users.put.bind(db.users, opts.id, body)

  res.end('OK')
}

The modules

var Router = require('routes-router')
var http = require('http')

var router = Router({
  errorHandler: function (req, res, err) {
    res.statusCode = 500
    res.end("500: Unknown error " + err.message)
  }
})

router.addRoute("/oops", function (req, res, opts, cb) {
  cb(new Error("oops!"))
})

http.createServer(router).listen(3000)

The modules

And many more!

A normal example

// require statements somewhere
var renderUserPage = require('./views/user-page.js');
var validateUser = require('./validations/user.js');
var router = Router();
router.addRoute('/user/:id', {
    GET: function* renderPage(req, res, opts) {
        var user = yield db.users.get.bind(db.users, opts.id);
        sendHtml(req, res, renderUserPage({
            title: 'Editing user ' + user.name,
            name: user.name, email: user.email
        }));
    },
    POST: function* updateUser() {
        var body = yield formBody.bind(null, req, res);
        var error = validateUser(body);
        if (error) yield error;
        yield db.users.put.bind(db.users, opts.id, body);
        redirecter(req, res, '/users/' + opts.id + '/edit');
    }
});
http.createServer(router).listen(3000);

Modules v Frameworks

Which is right for you

Modules v Frameworks

The pros

  • You structure your application
  • Individual versioning, pick and mix.
  • Distributed development, no lock in.

Module v Frameworks

The cons

  • No centralized contributions
  • Difficult to bake security in.
  • shoot yourself in the foot

`http-framework`

A collection of examples and documentation for this approach

Contributions welcome

Thanks.

@Raynos