Blog

Edge Computing and Developer Tools Part 2: How to Configure Your Development Environment

April 23, 2020 · by David Theobald ·

It’s easy to get started with EdgeWorkers. The first step is to sign up for the EdgeWorkers program. This series of posts focuses on how to get the most out of EdgeWorkers by using your existing tool set. In my previous post, we introduced EdgeWorkers, setting the stage for our development scenario. This post provides a step-by-step approach for configuring your development environment to tighten your Configure>Code>Confirm iteration loops.

Development Environment

A benefit of EdgeWorkers leveraging JavaScript is that you may already have your local development environment and tooling setup for other project work. You are free to use any operating system, IDE, and/or tooling that is compatible with ES6 JavaScript to code, build, and package your EdgeWorkers. For instance, my development environment consists of Ubuntu Xenial (16.04) via Windows Subsystem for Linux, and Visual Studio Code with Node.js and npm installed to help with code organization and packaging.

Through the course of building out this demo, we will be adding a few developer-focused tools to our development environment that are tightly integrated with EdgeWorkers, namely:

  • EdgeWorkers TypeScript definitions to help us understand syntax and data types for the EdgeWorkers JavaScript API, producing better code, sooner
  • Akamai Sandbox to help us deploy and test code changes without impacting real end users or other developers working on our website
  • Akamai CLI with EdgeWorkers and Sandbox packages to help us interact with EdgeWorkers as well as Sandbox management APIs for deploying code changes

Prerequisites

There are a few configuration tasks that are prerequisites before we can continue. Please work with your Akamai Admin to help with the following:

  • Ensure EdgeWorkers is included on your company’s Akamai contract — if not,  sign up for the EdgeWorkers program 
  • Provision credentials for Akamai’s OPEN APIs with access to Property Manager (PAPI), Akamai Sandbox, and EdgeWorkers — these are needed for API or CLI interactions
  • Install into your local development environment the Akamai CLI with EdgeWorkers and Sandbox packages
  • Ensure a secure Ion or DSA delivery property for your website already exists and includes a rule enabling EdgeWorkers behavior

For our example scenario here, I’ve built a secure Ion delivery property named we.makegolf.fun, which includes a rule matching the URL path /getpremium. If the rule matches inbound traffic, then the EdgeWorkers code bundle for “WeMakeGolfFun - Premium Check” (id: 3686) is enabled.

Let’s Go

To configure, code, and confirm that we’ve migrated the “Go Premium” logic from the origin to the Akamai Edge:

  1. Spin up an Akamai Sandbox instance that clones the Ion delivery property configuration for the website

  2. Use TypeScript constructs, Akamai’s EdgeWorkers JavaScript specification, and npm to replicate the "Go Premium" AJAX call within EdgeWorkers events and build it into an EdgeWorkers code bundle

  3. Update Akamai Sandbox with a newly-coded EdgeWorkers code bundle, and validate the transformations to achieve the intended result

  4. Once the EdgeWorkers code is complete, upload and activate it to Akamai’s secure delivery networks via the EdgeWorkers CLI

Step 1: Create an Akamai Sandbox Instance

First, we’ll build a sandbox instance that will be local and isolated to our development efforts that is based on the latest active version of our golf website’s delivery property. To do this, we can leverage the Akamai Sandbox CLI by providing the delivery property name, a version you wish to clone from, and an optional name for your sandbox instance. For example, the following command will create the GOLF_SANDBOX instance cloning from Version 10 of the delivery property we.makegolf.fun.

$ akamai sandbox create --property we.makegolf.fun:10 --name GOLF_SANDBOX

To see the details of the currently created sandbox instance, simply call the list command:

$ akamai sandbox list

Local sandboxes:

 

current  name                sandbox_id

-------  ------------------  ------------------------------------

YES      GOLF_SANDBOX        5007551b-92ed-42d4-94b2-2d181db6aa45

Let’s start our sandbox instance so we can verify everything is working on the website when it’s delivered through Akamai Sandbox. If this is your first time using Akamai Sandbox, it will also download and install the sandbox client, which facilitates the connection to the isolated edge machines and services. To kick things off, call the start command. You should see various information lines ending with a success message and the port the sandbox client is listening on.

$ akamai sandbox start

...

... INFO  c.a.devpops.connector.ConnectorMain - Successfully launched Akamai Sandbox Client

... INFO  c.a.devpops.connector.ConnectorMain - Sandbox Client running on port: 9550

Now, validate existing functionality of the website continues to work as expected through Akamai Sandbox. To ensure your test traffic is going through your sandbox instance, add an entry to your /etc/hosts file, mapping the test website’s hostname to localhost like so:

[prism:bash

]$ vi /etc/hosts
127.0.0.1       we.makegolf.fun

[/prism:bash]

Then append the port noted in the start-up message to all test URLs, such as:

http://we.makegolf.fun:9550/

Once satisfied that everything is working as expected, we have our baseline and can exit the sandbox client — essentially shutting down the tunnel over Port 9550 for now.

Step 2: Code, Build, and Package EdgeWorkers Events

The next step is to replicate the business logic for the “Go Premium” feature within EdgeWorkers events. Now we will build all of the files necessary and package them so we can pass the resulting archive to Akamai Sandbox. There are two required files within each EdgeWorkers code bundle:

  • main.js contains the JavaScript logic for each event you wish to execute
  • bundle.json is the manifest file indicating meta information about this archive, such as code version

Optional JavaScript files for helper functions or local data dictionaries can also be included when building the EdgeWorkers code bundle. Please note that there are code size limits enforced on upload so minification and code reduction techniques are recommended. Further details on how to create code bundles can be found in the EdgeWorkers User Guide.

flow chart

Before we start coding, let’s organize our files into a package to take advantage of the compile and build capabilities of npm. Leveraging npm isn’t a requirement for EdgeWorkers TypeScript bindings, but is shown here as a convenience. Alternatively, you can add TypeScript definitions directly into your IDE as a plug-in, such as with Visual Studio Code.

Assuming I want to create version 2.0.0 of the EdgeWorkers instance “WeMakeGolfFun - Premium Check” (id: 3686), let’s move to that working directory and initialize our npm package.  Calling npm init will create a package.json file containing meta information about this package such as its name, version, author, build scripts, module dependencies, etc. The settings I used are outputted below — feel free to enter the values you would like to use, as the only mandatory setting is that the entry point be main.js.

$ cd ~/dev/golf_website/edgeworkers/3686/2.0.0


$ 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.

 

See `npm help json` for definitive documentation on these fields

and exactly what they do.

 

Use `npm install <pkg>` afterwards to install a package and

save it as a dependency in the package.json file.

 

Press ^C at any time to quit.

package name: (2.0.0) getpremium-edgeworker

version: (1.0.0) 2.0.0

description: Offloads /getPremium AJAX call for WeMakeGolf.Fun landing page

entry point: (index.js) main.js

test command:

git repository:

keywords:

author: David Theobald

license: (ISC)

About to write to ~/dev/golf_website/edgeworkers/3686/2.0.0/package.json:

 

{

  "name": "getpremium-edgeworker",

  "version": "2.0.0",

  "description": "Offloads /getPremium AJAX call for WeMakeGolf.Fun landing page",

  "main": "main.js",

  "scripts": {

    "test": "echo \"Error: no test specified\" && exit 1"

  },

  "author": "David Theobald",

  "license": "ISC"

}

 

Is this OK? (yes) yes

Following the creation of package.json, we need to install a couple of development dependencies for TypeScript and the EdgeWorkers TypeScript definitions — npm can install those for us too:

$ npm install --save-dev typescript

npm notice created a lockfile as package-lock.json. You should commit this file.

 

+ typescript@3.8.2

added 1 package from 1 contributor and audited 1 package in 7.253s

found 0 vulnerabilities

 

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

 

+ @types/akamai-edgeworkers@1.0.1

added 1 package from 1 contributor and audited 2 packages in 3.561s

found 0 vulnerabilities

If you look inside package.json you will find this new stanza has been added referencing the latest versions of the required dependencies:

"devDependencies": {
    "@types/akamai-edgeworkers": "^1.0.1",
    "typescript": "^3.8.3"
  }

Since TypeScript is locally available within our package, we can customize its configuration to ensure the EdgeWorkers type definitions are available as well as ensuring when we go to compile our code into native JavaScript, we are using the right specification — EdgeWorkers is ES 6 (ES2015) compatible. To initiate the TypeScript configuration, create a new file named tsconfig.json within our working directory and include the following JSON stanza which defines the JavaScript specification TypeScript should compile into, as well as where the output .js file will be stored (the built directory in this example).

{
    "compilerOptions": {
        "module": "es2015",
        "target": "ES2015",
        "noImplicitAny": false,
        "outDir": "built",
        "rootDir": ".",
        "sourceMap": false
    },
    "exclude": [
        "node_modules"
    ]
}

Now we are ready to code our logic into the EdgeWorkers events. Since we want TypeScript to help verify the syntax and data expectations of EdgeWorkers objects, we need to create a main.ts file (note the “.ts” extension for TypeScript). In order to replicate the “Go Premium” logic that is currently on the content origin for the golf subscription website, we will need to provide a similar JSON payload for the “/getpremium” AJAX call as well as create a session cookie. The logic for these two steps is illustrated in the main.ts file below — notice that the first line references the EdgeWorkers types package we installed locally as a dev dependency:

/// <reference types="akamai-edgeworkers"/>
import {Cookies, SetCookie} from 'cookies';

export function onClientRequest(request : EW.MutableRequest & EW.HasRespondWith) {

  let cookies = new Cookies(request.getHeader('Cookie'));
  var isPremium = cookies.get('golfPremium');
  var premiumStatus = {premiumStatus: 'gold', statusFrom: 'edge'};

  if (isPremium === undefined) {
    request.respondWith(200, {}, JSON.stringify(premiumStatus));
  }
  else {
    request.respondWith(200, {}, JSON.stringify(isPremium));
  }
}

export function onClientResponse(request : EW.ImmutableRequest, response : EW.Response) {
 
  let cookies = new Cookies(request.getHeader('Cookie'));
  var isPremium = cookies.get('golfPremium');
  var premiumStatus = {premiumStatus: 'gold', statusFrom: 'edge'};

  if (isPremium === undefined) {

    var setPremiumCookie = new SetCookie({name: "golfPremium" , value: JSON.stringify(premiumStatus)});
    response.setHeader('Set-Cookie', setPremiumCookie.toHeader());
  }
  response.setHeader('X-Powered-By', 'Akamai EdgeWorkers');
}

At this point, we have a syntactically correct main.ts file representing the “Go Premium” business logic that we want to pull forward from the content origin to the Akamai Edge. Next, we must define the build tasks, requiring one last update to package.json — let’s remove the dummy test script placeholder that npm init added, add a package config variable to hold the EdgeWorker ID (3686 for this example), and define the build steps.  

The build steps must:

  1. Convert main.ts,the required EdgeWorkers code file, into main.js via tsc, the TypeScript compiler 

  2. Build bundle.json, the required EdgeWorkers manifest file, based on information in package.json

  3. Create an EdgeWorkers code bundle (tgz) that can be tested via Akamai Sandbox and, post-confirmation, will be deployed to Akamai delivery networks

Here is an example package.json that accomplishes these build steps:

{
  "name": "getpremium-edgeworker",
  "version": "2.0.0",
  "description": "Offloads /getPremium AJAX call for WeMakeGolf.Fun landing page",
  "main": "main.js",
  "config": {
    "ewid": "3686"
  },
  "scripts": {
    "build": "npm run build-ts",
    "build-ts": "tsc && npm run build-bundle-json",
    "build-bundle-json": "cd built && echo '{\"edgeworker-version\":\"'$npm_package_version'\",\"description\":\"'$npm_package_description'\"}' > bundle.json && npm run build-ew-tgz",
    "build-ew-tgz": "cd built && tar czvf ../../'ew_'$npm_package_config_ewid'_'$npm_package_version'.tgz' *",
    "postinstall": "npm run build"
  },
  "author": "David Theobald",
  "license": "ISC",
  "devDependencies": {
    "@types/akamai-edgeworkers": "^1.0.1",
    "typescript": "^3.8.3"
  }

}

Finally, we are ready to build the EdgeWorkers code bundle. Within our working directory for this package, call:

$ npm install

 

> getpremium-edgeworker@2.0.0 postinstall ~/dev/golf_website/edgeworkers/3686/2.0.0

> npm run build

 

> getpremium-edgeworker@2.0.0 build ~/dev/golf_website/edgeworkers/3686/2.0.0

> npm run build-ts

 

> getpremium-edgeworker@2.0.0 build-ts ~/dev/golf_website/edgeworkers/3686/2.0.0

> tsc && npm run build-bundle-json

 

> getpremium-edgeworker@2.0.0 build-bundle-json ~/dev/golf_website/edgeworkers/3686/2.0.0

> cd built && echo '{"edgeworker-version":"'$npm_package_version'","description":"'$npm_package_description'"}' > bundle.json && npm run build-ew-tgz

 

> getpremium-edgeworker@2.0.0 build-ew-tgz ~/dev/golf_website/edgeworkers/3686/2.0.0

> cd built && tar czvf ../../'ew_'$npm_package_config_ewid'_'$npm_package_version'.tgz' *

 

bundle.json

main.js

 

audited 2 packages in 9.01s

found 0 vulnerabilities

The output should be an EdgeWorkers code bundle named ew_3686_2.0.0.tgz, which can now be used for confirmation testing.

Step 3: Update Sandbox Instance With New EdgeWorkers Code and Confirm Changes

Now that we have a new EdgeWorkers code bundle to test, let’s update the sandbox to use this code instead of what may already be activated on the Akamai delivery networks (if anything). Again, we can leverage the Sandbox CLI to accomplish this. Once the code bundle has been updated in the sandbox, restart the sandbox client.

$ akamai sandbox update-edgeworker 3686 ~/dev/golf_website/edgeworkers/3686/ew_3686_2.0.0.tgz

done!


$ akamai sandbox start

...

... INFO  c.a.devpops.connector.ConnectorMain - Successfully launched Akamai Sandbox Client

... INFO  c.a.devpops.connector.ConnectorMain - Sandbox Client running on port: 9550

Validate that the new business logic is applied for the “Go Premium” AJAX call. If it is correct, the new EdgeWorkers code bundle is ready for upload and activation to the Akamai delivery networks. For example: 

http://we.makegolf.fun:9550/getpremium

This yields a JSON payload from the EdgeWorker instead of the content origin:

{
"premiumStatus": "gold",
"statusFrom": "edge"
}

We now know the business logic will work as desired when deployed to the Akamai delivery networks.

Step 4: Deploy New EdgeWorkers Code to Delivery Networks

Finally, we’ve arrived — we are ready to take our recently coded and confirmed EdgeWorkers code bundle and activate it to the Akamai delivery networks. The EdgeWorkers CLI makes easy work of this step by providing commands to upload your code bundle, activate per network (Akamai staging vs. production), and check the activation status. These steps are outlined below, starting with uploading:

$ akamai edgeworkers upload 3686 --bundle ~/dev/golf_website/edgeworkers/3686/ew_3686_2.0.0.tgz

----------------------------------------------------
--- New version uploaded for EdgeWorker Id: 3686 ---
----------------------------------------------------
edgeWorkerId  version  checksum  createdBy  createdTime
------------  -------  --------  ---------  --------------------
3686          2.0.0    < hash >  dtheobal   2020-01-30T23:19:46Z

Next, we need to activate EdgeWorkers Version 2.0.0 to the Akamai staging network:

$ akamai edgeworkers activate 3686 STAGING 2.0.0

--------------------------------------------------------------------------------------------
--- New Activation record created for EdgeWorker Id: 3686, version: 2.0.0, on network: STAGING ---
--------------------------------------------------------------------------------------------
edgeWorkerId  version  activationId  status     network  createdBy  createdTime
------------  -------  ------------  ---------  -------  ---------  --------------------
3686          2.0.0    2             PRESUBMIT  STAGING  dtheobal   2020-01-30T23:21:53Z

Lastly, we monitor the activation status via:

$ akamai edgeworkers status 3686 --versionId 2.0.0

--------------------------------------------------------------------------------------------
--- The following EdgeWorker Activations currently exist for account: <account>, ewId: 3686, version: 2.0.0, activationId: any ---
--------------------------------------------------------------------------------------------
edgeWorkerId  version  activationId  status   network  createdBy  createdTime
------------  -------  ------------  -------  -------  ---------  --------------------
3686          2.0.0    2             PENDING  STAGING  dtheobal   2020-01-30T23:21:53Z

Once the status indicates COMPLETE we can perform one last round of feature verification on the delivery network that you have deployed to (staging in this case). In our example, we would validate the new business logic applied for /getPremium — if correct, we’re done!

This is cool — now what?

If you found this demo compelling and see value in using edge computing within your website delivery needs, please sign up for our EdgeWorkers Beta Program to get some first-hand experience.

Have questions on EdgeWorkers? We are happy to chat about your use cases and requirements. Contact our team at edgeworkers@akamai.com.