-
-
Notifications
You must be signed in to change notification settings - Fork 17.4k
/
Copy pathindex.js
115 lines (91 loc) · 2.96 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* 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 repects 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)) 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, next){
res.send(users);
});
// example: http://localhost:3000/api/repos/?api-key=foo
app.get('/api/repos', function(req, res, next){
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: "Lame, can't find that" });
});
/* istanbul ignore next */
if (!module.parent) {
app.listen(3000);
console.log('Express started on port 3000');
}