Webtask

Documentation

Webtask Compilers

Write webtasks in domain specific languages

For customized documentation and ready to run samples, please log in.

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 to GET 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 a function (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 with function (error, func) signature that must be called when compilation is finished. The func 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.