Express Autoroute

Why you should never write any code





Presented by Chris Manson (@real_ate)

April 30, 2014 - NodeUpNorth Leeds

About me

Javascript professionally since 2009

Javascript more than 50% of the time since 2010

Now...

Learning how to write Javascript code

2009 - Greenfield Javascript heavy .NET app

Targeting IE only

... IE6

Learning how to write Javascript code

2010 - Greenfield single page app

Using Qooxdoo widget system

... and SOAP


Learning how to write Javascript code

2011 - Blooie was born

Greenfield ... well... Everything!

Bring on the decisions!

Best Practices VS CoC

This talk by past Chris from a Year ago: 

This talk now: 

What is Express?


  • A web application framework for node
  • Makes handling HTTP/S requests easy with middleware
  • Lots of built in functionality 
  • If you are handling HTTP requests, use Express.

Getting Started


$ npm install express 

var express = require('express');
var app = express();
app.get('/', function(req, res){
  res.send('Hello World!');
});
app.listen(3000);

$ curl localhost:3000
Hello World! 

Real apps > Getting Started

//# myapp/app.js

var express = require('express');
var app = express();

//Some inline routes
app.get('/me', function(req, res){ 
    res.json(req.session.user) //simplified
});

//Routes from other files
app.get('/analytics', require('./routes/analytics.js').trackEvent);

//Load a collection of routes from another file - IOC
require('./routes/verify.js')(app);

//Load a whole bunch of ungrouped routes
require('./routes').init(app);

And this was all in 1 file


Enter Express-Autoroute

$ npm install express-autoroute 
var express = require('express');
var app = express();
var autoroute = require('express-autoroute');

autoroute(app);

app.listen(3000);
//# routes/hello.js
    
module.exports.autoroute = {
    get: {
        '/hello' : function(req, res){
            res.send("Hello World!");
        }
    }
}
$ curl localhost:3000/hello
Hello World! 


Express-Autoroute

//# routes/hello.js
    
module.exports.autoroute = {
    get: {
        '/hello' : function(req, res){
            res.send("Hello World!");
        },
        '/hello/:type' : function(req, res){
            res.send("Hello " + req.params.type + "!");
        }
    }
}
$ curl localhost:3000/hello
Hello World! 

$ curl localhost:3000/hello/Everybody
Hello Everybody!

Express-Autoroute Folders

//# routes/api/goodbye.js
    
module.exports.autoroute = {
    get: {
        '/goodbye' : function(req, res){
            res.send("Goodbye cruel World!");
        },
        '/goodbye/:type' : function(req, res){
            res.send("Goodbye " + req.params.type + "!");
        }
    }
}
$ curl localhost:3000/api/goodbye
Goodbye cruel World! 

$ curl localhost:3000/api/goodbye/Everybody
Goodbye Everybody!

What is REST?


  • Representational state transfer
  • Defined in 2000 by Roy Fielding
  • ......

The "Right" way to do REST


  • For some REST is a rigidly defined architecture. That's fine!
  • For others REST is a concept used to communicate a style. This is also fine!
  • Be as pragmatic or dogmatic about REST as you want, there are no moral absolutes in software design.

For me:


Ember-Data

Connecting to a HTTP server

Action HTTP Verb URL
Find GET /people/123
Find All GET /people
Update PUT /people/123
Create POST /people
Delete DELETE /people/123


http://emberjs.com/guides/models/connecting-to-an-http-server/

Express + REST

var express = require('express');
var app = express();

app.post('/book', function(req, res){
  // Connect to a data source, create a book, assign to variable book
  res.json(201, book);
});
app.get('/book/:id', function(req, res){
  // Connect to a data source, read a book by id, assign to variable book
  res.json(200, book);
});
app.put('/book/:id', function(req, res){
  // Connect to a data source, update a book by id, assign to variable book
  res.json(200, book);
});app.delete('/book/:id', function(req, res){
  // Connect to a data source, delete a book by id
  res.send(204);
});

app.listen(3000);


Express-Autoroute REST

#// routes/book.js
var express = require('express');
var app = express();

module.exports.autoroute = {
    get: {
        '/book': function(req, res){ res.json(201, book); },
        '/book/:id': function(req, res){ res.json(200, book); }
    },
    put: {
        '/book/:id': function(req, res){ res.json(200, book); }
    },
    delete: {
        '/book/:id': function(req, res){ res.send(204); }
    }
}
app.listen(3000);
Much clearer , but still cumbersome for multiple REST resources.

Express-Autoroute Rest

//# routes/api/blacklists.js
    
module.exports.autoroute = {
    get: {
        '/blacklists' : [authentication, authorisation, get_all],
        '/blacklists/:id' : [authentication, authorisation, get]
    },
    post: {
        '/blacklists/:id' : [authentication, authorisation, update],
        '/blacklists' : [authentication, authorisation, create]
    },
    delete: {
        '/blacklists/:id' : [authentication, authorisation, del]
    }
};
function get_all(req, res){
    //do something
}

...

Enter Express-Autoroute-Json

$ npm install express-autoroute express-autoroute-json
var express = require('express');
var app = express();
var autoroute = require('express-autoroute');

autoroute(app);

app.listen(3000);
//# routes/book.js
var autorouteJson = require('express-autoroute-json');
var Chats = require('../db/models/Chats');

module.exports.autoroute = autorouteJson({
    model: Chats, //mongoose model object
    find: {}
})

And that Works!


Well... Almost

What works:                    

  • find
  • authentication
  • authorisation


What doesn't work:           

  • put
  • post
  • delete                    

Want support for these?


Talk to me and let me know you want them

Pull requests are welcome!

I'll probably be hacking on them on the 14th May (2014) 



Questions?






@real_ate
slides.com/real_ate
github.com/mansona
Made with Slides.com