The programming model
The webtask programming model supports three function signatures out of the box:
module.exports = function (cb) {...} module.exports = function (ctx, cb) {...} module.exports = function (ctx, req, res) {...}
In order to offer a different programming model, a layer must be built that will adapt between the custom programming model and one of the above. Webtask compilers enable such adaptation layer to exist outside of the webtask script itself.
The webtask compiler concept
Webtask compilers enable webtasks to be written in domain specific languages, such as:
- Node.js script with custom programming model
- Express, T-SQL, C#
- CoffeeScript, TypeScript
- Pug, Ejs
- anything else that can be transpiled to one of the three basic programming models
The webtask compiler concept introduces a first class "compilation" step for a webtask script. Webtask compilers are executed by the webtask runtime and run on the server side when a request to execute a webtask is made. Results of the compilation are subject the same caching mechanisms as if one of the built-in programming models were used. A webtask compiler is declaratively associated with a webtask script when a webtask is created which enables webtask code to focus exclusively on domain specific programming model.
A webtask compiler is a Node.js function that takes a string literal representing the webtask script and is responsible for returning a JavaScript function that matches one of the three basic programming models that the webtask runtime understands. If no webtask compiler is specified for a webtask, the script must use one of the three supported programming models directly.
Associating webtask script with a compiler
A webtask compiler is associated with a webtask script at the time of webtask creation using the metadata property wt-compiler
. This can be accomplished through the HTTP APIs when creating a webtask, or through the wt-cli
command, for example:
wt create hello.js --meta wt-compiler={value}
The value of thewt-compiler
property identifies the compiler using either of two mechanisms:
- Node.js module: The value must be
{module_name}[/{function_name}]
. The module must be available in the webtask environment. - HTTP[S] URL: The value must be
http[s]://...
URL that responds toGET request
with Node.js source code of the compiler.
When the webtask is called, webtask runtime will pass the webtask script for compilation to the specified compiler function. Result is cached and re-used on subsequent calls.
Creating a webtask compiler
In order to create a webtask compiler you must implement a Node.js function that accepts a webtask script in your domain specific language and transforms it into a JavaScript function in one of the three signatures supported by the webtask runtime:
module.exports = function (options, cb) { return cb(null, function (cb) { cb(null, options.script); }); };
The webtask compiler in the example above returns a JavaScript function that matches the simplest webtask programming model of function (cb) {...}
and simply returns the webtask script itself as a result of its execution.
The webtask compiler function accepts an options object and a callback:
options.script
is the webtask script in domain specific language.-
options.secrets
is a hash of all secret parameters the webtask has been created with. -
options.nodejsCompiler
is afunction (script, callback)
function which implements the default compilation logic for Node.js webtasks that is used if a custom compiler is not specified. This is provided as an optional facility to simplify implementation of compilers that simply transform one JavaScript programming model into another. -
callback
is a function withfunction (error, func)
signature that must be called when compilation is finished. Thefunc
must be a JavaScript function in one of the three signatures supported natively by webtasks.
Once the webtask compiler is implemeted, you must host it somewhere where it can be referenced by an HTTPS URL, for example in S3, on a CDN, or on Github. We have uploaded our example compiler here.
Create the webtask using wt create
and use the meta
tag to refer to the webtask compiler via HTTPS. For our example, we want to create a webtask based on the contents of a foo.js
file, and we want to compile it using the compiler we have created at the previous steps:
$ wt create foo.js --meta wt-compiler=https://gist.githubusercontent.com/tjanczuk/14f67be8bb73f58a5d3c371605558379/raw/a8d0b2539f2904ae22d857ea8c0c0bca4ff8f7ac/reflector_compiler.js
Webtask compiler versioning
There are two mechanisms that can be used to version webtask compilers depending on the scenario:
- Non-breaking: New compiler code can be slipstreamed into existing Node.js module or HTTP[S] URL. This is suitable for progressive, backwards-compatible enhancements. The key benefit of this approach is that existing webtasks do not have to be modified, they remain associated with the
wt-compiler
specified at the time of their creation. - Breaking/New: Brand new compiler code can support completely different domain specific language (e.g. C# instead of Node.js). This is particularly suitable for breaking changes that require explicit opt-in by the author of the webtask code. In order to use a new compiler, a new webtask must be created or the old one re-created with the new value of
wt-compiler
and appropriately modified webtask script.
Webtask compiler examples
You can review more webtask compiler examples here.