diff --git a/.gitignore b/.gitignore index 32451fc..c46c009 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules/** build + +#template diff --git a/template/node10-express/function/handler.js b/template/node10-express/function/handler.js index a449950..d005d30 100644 --- a/template/node10-express/function/handler.js +++ b/template/node10-express/function/handler.js @@ -1,12 +1,64 @@ "use strict" -module.exports = (event, context) => { - let err; +// callback version +const delayCallback = cb => { + const min = 1; // 1 sec + const max = 5; // 5 sec + const delay = Math.round((Math.random() * (max - min) + min)); + setTimeout(() => cb(delay), delay * 1000); +} + +module.exports = (event, context, next) => { + delayCallback(delay => { + const result = { + status: "You said: " + JSON.stringify(event.body), + delay + }; + + context + .status(200) + .succeed(result); + + next(); + }) +} + +// Uncomment the following line to use it in the promise or async/await versions +// const delayPromise = () => new Promise((resolve, reject) => delayCallback(delay => resolve(delay)) ) + +// Promise version +/* +module.exports = (event, context) => new Promise((resolve, reject) => { + delayPromise() + .then(delay => { + const result = { + status: "You said: " + JSON.stringify(event.body), + delay + }; + + context + .status(200) + .succeed(result); + + return resolve(context); + }) +}); +*/ + +// async/await version +/* +module.exports = async (event, context) => { + const delay = await delayPromise(); + const result = { - status: "You said: " + JSON.stringify(event.body) + status: "You said: " + JSON.stringify(event.body), + delay }; context .status(200) .succeed(result); + + return context; } +*/ \ No newline at end of file diff --git a/template/node10-express/index.js b/template/node10-express/index.js index 8c85f48..3c6f1fe 100644 --- a/template/node10-express/index.js +++ b/template/node10-express/index.js @@ -14,6 +14,8 @@ app.use(bodyParser.raw()); app.use(bodyParser.text({ type : "text/*" })); app.disable('x-powered-by'); +let isObject = a => !!a && (a.constructor === Object); + class FunctionEvent { constructor(req) { this.body = req.body; @@ -25,59 +27,69 @@ class FunctionEvent { } class FunctionContext { - constructor(cb) { - this.value = 200; - this.cb = cb; - this.headerValues = {}; + constructor() { + this.statusCode = 200; + this.headerValues = {}; } status(value) { - if(!value) { - return this.value; + if (value) { + this.statusCode = value; } - this.value = value; return this; } headers(value) { - if(!value) { - return this.headerValues; + if(value && value.constructor === Object) { + this.headerValues = value; } - this.headerValues = value; - return this; + return this; } succeed(value) { - let err; - this.cb(err, value); + this.succeedValue = (Array.isArray(value) || isObject(value)) ? JSON.stringify(value) : value; } - fail(value) { - let message; - this.cb(value, message); + fail(message) { + this.statusCode = 500; + this.failMessage = message; } } -var middleware = (req, res) => { - let cb = (err, functionResult) => { - if (err) { - console.error(err); - return res.status(500).send(err); - } +const middleware = (req, res) => { + let fnEvent = new FunctionEvent(req); + let fnContext = new FunctionContext(); - if(isArray(functionResult) || isObject(functionResult)) { - res.set(fnContext.headers()).status(fnContext.status()).send(JSON.stringify(functionResult)); - } else { - res.set(fnContext.headers()).status(fnContext.status()).send(functionResult); + const sendFail = () => { + res.status(500).send(fnContext.failMessage); + } + + const handleResult = result => { + if (fnContext.failMessage) { + sendFail() } - }; + else { + res.set(fnContext.headers).status(fnContext.statusCode).send(fnContext.succeedValue); + } + } - let fnEvent = new FunctionEvent(req); - let fnContext = new FunctionContext(cb); + let next = () => handleResult(fnContext); + + const result = handler(fnEvent, fnContext, next); - handler(fnEvent, fnContext, cb); + if (result instanceof FunctionContext) { + handleResult(result); + } + else if (result instanceof Promise) { + result + .then(asyncResult => handleResult(asyncResult)) + .catch(err => { + fnContext.fail(err); + handleResult(fnContext); + }) + } }; app.post('/*', middleware); @@ -91,11 +103,3 @@ const port = process.env.http_port || 3000; app.listen(port, () => { console.log(`OpenFaaS Node.js listening on port: ${port}`) }); - -let isArray = (a) => { - return (!!a) && (a.constructor === Array); -}; - -let isObject = (a) => { - return (!!a) && (a.constructor === Object); -};