Simplyfing Webtask Configuration Management
Dec 27th, 2023 update: Webtasks have been deprecated.
I have many little apps all implemented as Webtasks. I’ve shown many of these in previous posts such as:
In some cases, a single app is made up of a couple of different Webtasks. Very often when there’re many, it’d be a combination of an interactive and a batch one (the former being an Express based WT, the latter a simple cron).
One issue I was having is keeping configuration in synch across all. Because these are simple apps with shared backends (e.g. they all use the same MongoDB for storage or the same Twilio account for messaging), I found myself copy-pasting configuration values across all Webtasks using the built-in secrets capability.
These values don’t change very often, but when they do, it is a royal PIA to update them all. So I came with a simpler method.
A Configuration Webtask
This is 20 lines of code Express Webtask:
'use latest';
import express from 'express';
import Webtask from 'webtask-tools';
import bodyParser from 'body-parser';
const app = express();
app.use(bodyParser.json());
app.get('/', function (req, res) {
var auth = req.get('Authorization');
if(!auth || auth !== req.webtaskContext.data['CONFIG_API_TOKEN']){
res.statusCode = 403;
return res.send("Unauthorized");
}
res.json(req.webtaskContext.data);
});
module.exports = Webtask.fromExpress(app);
All it does is send back a JSON object with all secrets (provided the access_token
is valid)
Using the Configuration WT
All my Express APIs/mini-Websites now include the following middleware:
var config;
server.use((req, res, next) => {
if(config){
return next();
}
request.get('https://{MY WEBTASK URL}/config',
{
headers: {
Authorization: req.webtaskContext.data['CONFIG_API_KEY']
}
},
(r, s, b) => {
if(s.statusCode !== 200){ return next('Cannot load configuration');}
config = JSON.parse(b);
next();
});
});
Because it runs first, config
is always populated. Now anywhere in code I can do:
server.get('/test', (req, res, next) => {
const { MONGO_URL, GOOGLE_TRANSLATE_API_KEY } = config;
...
do something here with the config values ^
...
});
Now the only secret I need to keep in each individual WTs is CONFIG_API_KEY, which happens to be the access_token
for the configuration API.