-
Notifications
You must be signed in to change notification settings - Fork 6
/
server.js
152 lines (130 loc) · 4.72 KB
/
server.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
var express = require('express'),
partials = require('express-partials'),
bodyParser = require('body-parser'),
app = express(),
ejs = require('ejs'),
mongoose = require('mongoose'),
path = require('path')
jsonMarkup = require('json-markup');
if (process.env.BASE_URI) {
global.baseUri = process.env.BASE_URI.replace(/\/$/, '');
} else {
require('dns').lookup(require('os').hostname(), function(err, ipAddress, fam) {
global.baseUri = "http://"+ipAddress+":"+(process.env.PORT || 3000);
});
}
// Handler for DB Connection Errors
mongoose.connection.on('error', function(err) {
console.error("MongoDB error", err);
});
// Connect to the Mongo DB (mLab on Heroku uses MONGOLAB_URI)
mongoose.connect( process.env.MONGODB || process.env.MONGOLAB_URI || 'mongodb://localhost/structured-data' );
// Configure Express to handle JSON requests
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// We have to set a template engine for Express
app.set('view engine', 'ejs');
app.engine('ejs', ejs.__express);
partials.register('.ejs', ejs);
app.use(partials());
// Serve static content from the public directory
app.use(express.static(path.join(__dirname, 'public')));
app.set('port', process.env.PORT || 3000);
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", process.env.ALLOW_ORIGIN || "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Api-Key");
res.setHeader("Access-Control-Allow-Methods", "INFO, GET, PUT, POST, DELETE, HEAD");
res.locals.siteName = process.env.SITE_NAME || "Structured Data API";
res.locals.baseUri = global.baseUri;
next();
});
/**
* Parse and load schemas as databases models
*/
var schemaParser = require('./lib/schema-parser');
schemaParser.collectionName = process.env.DEFAULT_COLLECTION || 'entities';
schemaParser.schemaDir = process.env.SCHEMAS || __dirname+"/schemas/";
schemaParser
.load()
.then(function(schemas) {
var listOfSchemas = [];
for (var schemaName in schemas.schemas) listOfSchemas.push(schemaName);
/**
* Homepage
*/
app.get('/', function(req, res, next) {
res.render('index', { schemas: listOfSchemas });
});
/**
* Return webpage with list of documentation for all supported schemas
*/
app.get('/docs', function(req, res, next) {
res.render('docs', { schemas: listOfSchemas });
});
/**
* Return webpage with information about a schema
*/
app.get('/docs/:name/schema', function(req, res, next) {
if (schemas.schemas[req.params.name]) {
if (req.headers.accept && req.headers.accept.indexOf('json') > -1) {
res.status(200).json(schemas.schemas[req.params.name].schema);
} else {
res.render('schema', { schemaName: schemas.schemas[req.params.name].model.modelName, schema: jsonMarkup(schemas.schemas[req.params.name].schema) } );
}
} else {
res.status(404).json({error: 400, message: "Schema not found", requestedUrl: req.originalUrl });
}
});
/**
* Return webpage with information about an API for a schema
*/
app.get('/docs/:name', function(req, res, next) {
if (schemas.schemas[req.params.name]) {
res.render('api', { schemaName: schemas.schemas[req.params.name].model.modelName, schema: jsonMarkup(schemas.schemas[req.params.name].schema) } );
} else {
res.status(404).json({error: 400, message: "Schema not found", requestedUrl: req.originalUrl });
}
});
/**
* Routes for for the API
*/
var apiRoutes = require('./routes/api');
app.use('/', apiRoutes(schemas));
/**
* 500 Error Handler
*/
app.use(function (err, req, res, next) {
// Handle 404s
if (err.message
&& (~err.message.indexOf('not found')
|| (~err.message.indexOf('Cast to ObjectId failed')))) {
return next();
};
console.error(err);
if (err.stack) console.error(err.stack);
res.status(500).json({error: 500, message: err.message });
});
/**
* 404 File Not Found Handler
*/
app.use(function(req, res, next) {
res.status(404).json({error: 400, message: "File not found", requestedUrl: req.originalUrl });
});
// If running in test mode we don't actually need to start a listner that binds to a port
if (process.env.NODE_ENV == "test")
return;
/**
* Start listening
* @TODO Check MongoDB is up
*/
require('dns').lookup(require('os').hostname(), function(err, ipAddress, fam) {
app.listen(app.get('port'), function() {
console.log('Server running at http://%s:%d in %s mode', ipAddress, app.get('port'), app.get('env'));
});
});
})
.catch(function(err) {
console.error("Unable to start server as failed to load schemas: ",err);
process.exit(0);
});
module.exports = app;