-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
133 lines (112 loc) · 4.5 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
// default the NODE_ENV to 'development'.
// To start in 'production' mode using `pm2`, start like so
// $ NODE_ENV=production pm2 start server.js --name=z3
//
const env = process.env.NODE_ENV || 'development';
import process from 'node:process';
import { Config } from '@punkish/zconfig';
const config = new Config().settings;
import { server } from './app.js';
import { coerceToArray, getCache, getCacheKey } from './lib/routeUtils.js';
import { cronJobs } from './plugins/cron.js';
// Function to initialize and start the server!
//
const start = async () => {
const opts = {
// setting 'exposeHeadRoutes' to false ensures only 'GET' routes are
// created without their accompanying 'HEAD' routes
//
exposeHeadRoutes: false,
logger: config.pino.opts,
// ajv options are provided in the key 'customOptions'. This is
// different from when ajv is called in a stand-alone script (see
// `validate()` in lib/zql/z-utils.js)
//
ajv: {
customOptions: config.ajv.opts
}
};
try {
const fastify = await server(opts);
// save the original request query params for use later because the
// query will get modified after schema validation
//
// fastify.addHook('preValidation', async (request) => {
// request.origQuery = JSON.parse(JSON.stringify(request.query));
// });
// the following takes care of cols=col1,col2,col3 as sent by the
// swagger interface to be validated correctly by ajv as an array. See
// `coerceToArray()` in routeUtils().
//
fastify.addHook('preValidation', async (request) => {
coerceToArray(request, 'cols');
coerceToArray(request, 'communities');
});
// if the query results have been cached, we send the cached value back
// and stop processing any further
//
fastify.addHook('preHandler', async (request, reply) => {
// all of this makes sense only if refreshCache is not true
//
if (!request.query.refreshCache) {
const path = request.url.split('/')[2];
const resourceName = path
? path.split('?')[0]
: '';
// The following is applicable *only* if a resourceName is
// present
//
if (resourceName) {
const cacheKey = getCacheKey(request);
const cache = getCache({
dir: config.cache.base,
namespace: resourceName,
duration: request.query.cacheDuration
? request.query.cacheDuration * 24 * 60 * 60 * 1000
: config.cache.ttl
});
let res = await cache.get(cacheKey);
if (res) {
const response = {
item: res.item,
stored: res.stored,
ttl: res.ttl,
//pre: true,
cacheHit: true,
};
reply.hijack();
// since we are sending back raw response, we need to
// add the appropriate headers so the response is
// recognized as JSON and is CORS-compatible
//
reply.raw.writeHead(200, {
'Content-Type': 'application/json; charset=utf-8',
'Access-Control-Allow-Origin': '*'
});
reply.raw.end(JSON.stringify(response));
return Promise.resolve('done');
}
}
}
});
await fastify.listen({ port: config.port, host: config.address });
fastify.log.info(`… in ${env.toUpperCase()} mode`);
// We run the cronJobs onetime on initializing the server so the
// queries are cached
// for (const {qs} of cronJobs) {
// try {
// await fastify.inject(qs);
// }
// catch(error) {
// console.error(error);
// }
// }
}
catch (err) {
console.log(err);
process.exit(1);
}
};
// Start the server!
//
start();