Blog

Typescript Bindings

Introducing TypeScript Bindings for EdgeWorkers

March 27, 2020 · by Evan Hughes ·

This blog is part of the Akamai Platform Release, where we’re giving you all the details about what Akamai has added and improved for developers! You can view all of our updates here.  

We're excited to announce that we've published TypeScript bindings to the EdgeWorkers JavaScript API.

TypeScript is a superset of JavaScript that provides static typing, which means you can find problems at compile time, rather than run time. It has excellent integrated development environment (IDE) and editor support, so you can build EdgeWorkers in the comfort of your favorite TypeScript environment! 

Here's a sneak peek of the kind of hints VS Code can provide when you're typing:

code snippet examples

In this post, we’ll walk through how to install this new type definition and how to create your first TypeScript EdgeWorker. 

Prerequisites 

You should already have provisioned an EdgeWorkers script on your property and have a working TypeScript (version 3.5.1+) development environment

Create a New Project

To make a home for your new project. Create a new directory, cd into it, and run tsc --init:

$ mkdir ts-ew-hello
$ cd ts-ew-hello
$ tsc --init
message TS6071: Successfully created a tsconfig.json file.

Since you'll probably want to install the dependency locally, run npm init to create an NPM package:

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
...

Hit return for reasonable defaults. 

Configure the Project

Since the EdgeWorkers JavaScript runtime supports ECMAScript 2015 (also known as ES 6), modify your tsconfig.json to set the target and module generation to be es2015 compatible. The generated file is full of helpful comments, but the values for the target and module generation should look like:

{
 "compilerOptions": {
    "target": "ES2015",
    "module": "es2015",
//...
}

Install the TypeScript Bindings

The EdgeWorkers bindings have been distributed as part of DefinitelyTyped type definitions. Install them with:

$ npm install --save-dev @types/akamai-edgeworkers

Create an EdgeWorker

Your EdgeWorker will live in a file named main.ts, and needs to follow a special shape. Create main.ts in your editor, and paste the following code into it:

/// <reference types="akamai-edgeworkers"/>

export function onClientRequest(request : EW.IngressClientRequest) {}
export function onOriginRequest(request : EW.IngressOriginRequest) {}
export function onOriginResponse(request: EW.EgressOriginRequest, response: EW.EgressOriginResponse) {}
export function onClientResponse(request: EW.EgressClientRequest, response: EW.EgressClientResponse) {}

Let's take a brief tour of the file:

  1. Line 1 references the EdgeWorkers package. It pulls the EdgeWorkers types into the environment, but doesn't generate import statements in the transpiled JavaScript. That's exactly what we need, because those types are defined by the EdgeWorkers runtime and don't need explicit inclusion. 

  2. Line 3 defines the client request callback that fires when Akamai first receives a browser request. The single argument is a modifiable representation of the request (the EW.IngressClientRequest). Any changes you make to the request will propagate to your origin server.

  3. Line 4 defines the onOriginRequest() callback, which fires before Akamai makes a request to your origin server. You can use the request object to modify what is sent to the origin. 

  4. The onOriginResponse() callback on line 5 is called after a response has been received from your origin. At this point, it's too late to change anything on the request, but the response can be modified. Changes made to the response object will be sent to the client. 

  5. onClientResponse() on line 6 is the final callback in request processing. It fires before the request leaves the Akamai edge. As with the previous callback, you can modify the response. 

Update the EdgeWorker so it terminates processing during onClientRequest:

/// <reference types="akamai-edgeworkers"/>


export function onClientRequest(request : EW.IngressClientRequest) {
    request.respondWith(200, {}, "Hello TypeScript!");
}

As the snippet shows, you can remove the unused EdgeWorker callbacks, which will provide a very small performance improvement. The respondWith() method will set the status code and body of the response. 

Compile the TypeScript. You can do that by running the command-line compiler, or using your favourite IDE. Using the command-line: 

$ tsc
$

There shouldn't be any output, because the input files are well-formed. If you get an error that includes the text TS1084: Invalid 'reference' directive syntax, then you need to upgrade your TypeScript compiler to version 3.5.1.

The compiler should write a main.js to the same directory. It will contain:

/// <reference types="akamai-edgeworkers"/>
export function onClientRequest(request) {
    request.respondWith(200, {}, "Hello TypeScript!");
}

You can create a package tarball out of the file and publish the EdgeWorker normally. 

Using Built-in Modules

Akamai provides a number of built-in modules, including parameter parsing and cookie management. The module APIs are defined in the same akamai-edgeworkers package listed above and can be referenced with imports.

Here we use the query parameter module to personalize the hello world:

/// <reference types="akamai-edgeworkers"/>

import URLSearchParams from 'url-search-params';

export function onClientRequest(request : EW.IngressClientRequest) {
    var params = new URLSearchParams(request.query);
 
    var who = params.get('who') || 'parameter world';
    request.respondWith(200, {}, `Hello ${who}!`);
}

If you deploy that EdgeWorker, you'll see that it emits "Hello parameter world!" for requests without a query string, or the value of who when that is specified.

To learn more about EdgeWorkers - including more on our use cases and Git repository of sample codes - visit the EdgeWorkers home page.