grist-data-gateway/gateway.cjs
2025-09-07 19:34:30 +00:00

48 lines
1.7 KiB
JavaScript

const http = require("http");
const Redis = require("ioredis");
const REDIS_HOST = process.env.REDIS_HOST || "data_jobs";
const REDIS_PORT = Number(process.env.REDIS_PORT || 6379);
const JOB_QUEUE = process.env.JOB_QUEUE || "grist:jobs";
const RES_QUEUE = process.env.RESULT_QUEUE || "grist:results";
const redis = new Redis({ host: REDIS_HOST, port: REDIS_PORT });
function cors(res){
res.setHeader("Access-Control-Allow-Origin","*");
res.setHeader("Access-Control-Allow-Methods","GET, POST, OPTIONS");
res.setHeader("Access-Control-Allow-Headers","*");
}
const server = http.createServer(async (req, res) => {
cors(res);
if (req.method === "OPTIONS") { res.writeHead(204); return res.end(); }
const path = req.url.split("?")[0];
if (req.method === "GET" && path === "/health") {
res.writeHead(200, {"content-type":"text/plain"}); return res.end("ok");
}
if (req.method === "GET" && (path === "/places" || path === "/api/places")) {
try {
await redis.lpush(JOB_QUEUE, "places");
const reply = await redis.blpop(RES_QUEUE, 8);
if (!reply) {
res.writeHead(202, {"content-type":"application/json"});
return res.end('{"ok":false,"status":"queued-or-timeout"}');
}
const [, value] = reply;
res.writeHead(200, {"content-type":"application/json"});
return res.end(JSON.stringify({ ok:true, raw:value }));
} catch (e) {
res.writeHead(500, {"content-type":"application/json"});
return res.end(JSON.stringify({ ok:false, error:e.message }));
}
}
res.writeHead(404, {"content-type":"application/json"});
res.end('{"error":"not found"}');
});
server.listen(8080, "0.0.0.0", () => console.log("[gateway] listening 8080"));