-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathserver.js
157 lines (146 loc) · 4.31 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
153
154
155
156
157
const express = require('express');
const app = express();
const rp = require('request-promise');
const port = process.env.PORT || 1122;
const cors = require('cors');
app.use(cors({ origin: true }));
const util = require('./helpers/util');
const starwars = require('./controllers/starwars');
const flatCache = require('flat-cache');
let cache = flatCache.load('starwarsCache', './cache');
/**
* middleware to log requests
* @param {object} req request
* @param {object} res response
* @param {function} next callback
*/
const requestTime = function(req, res, next) {
req.requestTime = Date.now();
console.log('method ' + req.method + ' and url ' + req.url);
console.log('request came across at ' + req.requestTime);
next();
};
app.use(requestTime);
/**
* middleware to cache responses
* code taken from scotch.io tutorial here
* https://scotch.io/tutorials/how-to-optimize-node-requests-with-simple-caching-strategies
* Additionally, this method does not update the cache file (notice the true value being passed to the save call).
* This is fine since the data does not change frequently.
* A good future improvement would be to build in a cache refresh here.
* @param {object} req
* @param {object} res
* @param {function} next
*/
let cacheMiddleware = (req, res, next) => {
let key = '__express__' + req.url;
let cacheContent = cache.getKey(key);
if (cacheContent) {
res.send(JSON.parse(cacheContent));
} else {
res.sendResponse = res.send;
res.send = body => {
cache.setKey(key, body);
cache.save(true);
res.sendResponse(body);
};
next();
}
};
app.use(cacheMiddleware);
/**
* Passthrough to the films route in SWAPI.
* @return {array} array of star wars films
*/
app.get('/films-list', async (req, res) => {
try {
const filmList = await starwars.filmList();
res.status(200).send(filmList);
} catch (error) {
console.log(error.message);
res.status(500).send(error.message);
}
});
/**
* Retrieves all the data for a specific film based on episode number (and not release order)
* @param {string} episode episode number
* @return {object} metadata about the star wars film specified in the parameters
*/
app.get('/film/:episode', async (req, res) => {
try {
const filmId = util.translateEpisode(req.params.episode);
const film = await starwars.film(filmId);
res.status(200).send(film);
} catch (error) {
console.log(error.message);
res.status(500).send(error.message);
}
});
/**
* Passthrough for people route in SWAPI.
* @param {string} id id of person in SWAPI
* @return {object} metadata of person selected
*/
app.get('/people/:id', async (req, res) => {
try {
const person = await starwars.people(req.params.id);
res.status(200).send(person);
} catch (error) {
res.status(500).send(error.message);
}
});
/**
* Passthrough for planet route in SWAPI.
* @param {string} id id of planet in SWAPI
* @return {object} metadata of planet selected
*/
app.get('/planet/:id', async (req, res) => {
try {
const planet = await starwars.planets(req.params.id);
res.status(200).send(planet);
} catch (error) {
res.status(500).send(error.message);
}
});
/**
* Passthrough for starship route in SWAPI.
* @param {string} id id of starship in SWAPI
* @return {object} metadata of starship selected
*/
app.get('/starship/:id', async (req, res) => {
try {
const starship = await starwars.starship(req.params.id);
res.status(200).send(starship);
} catch (error) {
console.log(error.message);
res.status(500).send(error.message);
}
});
/**
* Passthrough for call to vehicle route in SWAPI.
* @param {string} id id of vehicle in SWAPI
* @return {object} metadata of vehicle selected
*/
app.get('/vehicle/:id', async (req, res) => {
try {
const vehicle = await starwars.vehicles(req.params.id);
res.status(200).send(vehicle);
} catch (error) {
res.status(500).send(error.message);
}
});
/**
* Passthrough for call to species route in SWAPI.
* @param {string} id id of species in SWAPI
* @return {object} metadata of species selected
*/
app.get('/species/:id', async (req, res) => {
try {
const species = await starwars.species(req.params.id);
res.status(200).send(species);
} catch (error) {
res.status(500).send(error.message);
}
});
app.listen(port);
module.exports = app;