118 lines
3.0 KiB
JavaScript
118 lines
3.0 KiB
JavaScript
'use strict'
|
|
|
|
/**
|
|
* Module dependencies.
|
|
*/
|
|
|
|
var express = require('../../');
|
|
|
|
var app = module.exports = express();
|
|
|
|
// create an error with .status. we
|
|
// can then use the property in our
|
|
// custom error handler (Connect respects this prop as well)
|
|
|
|
function error(status, msg) {
|
|
var err = new Error(msg);
|
|
err.status = status;
|
|
return err;
|
|
}
|
|
|
|
// if we wanted to supply more than JSON, we could
|
|
// use something similar to the content-negotiation
|
|
// example.
|
|
|
|
// here we validate the API key,
|
|
// by mounting this middleware to /api
|
|
// meaning only paths prefixed with "/api"
|
|
// will cause this middleware to be invoked
|
|
|
|
app.use('/api', function(req, res, next){
|
|
var key = req.query['api-key'];
|
|
|
|
// key isn't present
|
|
if (!key) return next(error(400, 'api key required'));
|
|
|
|
// key is invalid
|
|
if (apiKeys.indexOf(key) === -1) return next(error(401, 'invalid api key'))
|
|
|
|
// all good, store req.key for route access
|
|
req.key = key;
|
|
next();
|
|
});
|
|
|
|
// map of valid api keys, typically mapped to
|
|
// account info with some sort of database like redis.
|
|
// api keys do _not_ serve as authentication, merely to
|
|
// track API usage or help prevent malicious behavior etc.
|
|
|
|
var apiKeys = ['foo', 'bar', 'baz'];
|
|
|
|
// these two objects will serve as our faux database
|
|
|
|
var repos = [
|
|
{ name: 'express', url: 'https://github.com/expressjs/express' },
|
|
{ name: 'stylus', url: 'https://github.com/learnboost/stylus' },
|
|
{ name: 'cluster', url: 'https://github.com/learnboost/cluster' }
|
|
];
|
|
|
|
var users = [
|
|
{ name: 'tobi' }
|
|
, { name: 'loki' }
|
|
, { name: 'jane' }
|
|
];
|
|
|
|
var userRepos = {
|
|
tobi: [repos[0], repos[1]]
|
|
, loki: [repos[1]]
|
|
, jane: [repos[2]]
|
|
};
|
|
|
|
// we now can assume the api key is valid,
|
|
// and simply expose the data
|
|
|
|
// example: http://localhost:3000/api/users/?api-key=foo
|
|
app.get('/api/users', function (req, res) {
|
|
res.send(users);
|
|
});
|
|
|
|
// example: http://localhost:3000/api/repos/?api-key=foo
|
|
app.get('/api/repos', function (req, res) {
|
|
res.send(repos);
|
|
});
|
|
|
|
// example: http://localhost:3000/api/user/tobi/repos/?api-key=foo
|
|
app.get('/api/user/:name/repos', function(req, res, next){
|
|
var name = req.params.name;
|
|
var user = userRepos[name];
|
|
|
|
if (user) res.send(user);
|
|
else next();
|
|
});
|
|
|
|
// middleware with an arity of 4 are considered
|
|
// error handling middleware. When you next(err)
|
|
// it will be passed through the defined middleware
|
|
// in order, but ONLY those with an arity of 4, ignoring
|
|
// regular middleware.
|
|
app.use(function(err, req, res, next){
|
|
// whatever you want here, feel free to populate
|
|
// properties on `err` to treat it differently in here.
|
|
res.status(err.status || 500);
|
|
res.send({ error: err.message });
|
|
});
|
|
|
|
// our custom JSON 404 middleware. Since it's placed last
|
|
// it will be the last middleware called, if all others
|
|
// invoke next() and do not respond.
|
|
app.use(function(req, res){
|
|
res.status(404);
|
|
res.send({ error: "Sorry, can't find that" })
|
|
});
|
|
|
|
/* istanbul ignore next */
|
|
if (!module.parent) {
|
|
app.listen(3000);
|
|
console.log('Express started on port 3000');
|
|
}
|