Need cloud computing? Get started now

Manage Akamai Features at the Edge with EdgeWorkers and EdgeKV

Akamai Wave Blue

Written by

Philip McGuinness

November 22, 2022

Akamai Wave Blue

Written by

Philip McGuinness

Philip McGuinness is a Senior Technical Solutions Architect at Akamai Technologies.
When dealing with hundreds or thousands of applications with different owners, it is possible that some applications will require different features.

As user populations grow in size, organizations often need to tailor their website’s content and functionality to different market segments. In this blog, you'll learn how EdgeWorkers can help you create and deploy microservices on the largest distributed serverless network, while EdgeKV can help you build data-driven EdgeWorkers applications.

Unpacking challenges to tailoring web content

Consider a real-world example of a small, centralized IT team that manages the Akamai CDN for a large, multidivision enterprise. When dealing with hundreds or thousands of applications with different owners, it is possible that some applications will require different features. These variations may be application-specific, or may include Akamai features only usable by one division of the enterprise.

In some cases, you may want to allow business-unit application owners to choose whether to enable or disable features such as page caching. This way, apps with highly static pages can enable caching, while others with more dynamic pages won’t do any caching.

Alternatively, think about software as a service (SaaS) providers that integrate Akamai CDN with their services. These providers would need to be flexible to accommodate thousands of customers. 

To this end, they could offer a premium plan that includes features that they’ll want to control availability, such as automatic image optimization using Akamai Image & Video Manager. They could use Akamai EdgeWorkers in conjunction with EdgeKV to control precisely how these CDN features are made available to their customers on a per-application basis.

Managing the Akamai configuration with EdgeWorkers

Properly tailoring content on a per-user basis can be broken down into four simple steps:

  1. Store all the CDN features for enabling and disabling each application as JSON objects in EdgeKV.
  2. Use EdgeWorkers to extract the hostname from each request, and set the hostname to the key to retrieve the configuration from EdgeKV. 
  3. Parse the JSON from EdgeKV with EdgeWorkers, and dynamically set the CDN feature variables needed to either enable or disable. These variables can then be read from within Property Manager.
  4. Toggle individual features, such as caching or image optimization, on and off depending on the value read.
Akamai features at the edge figure 1

EdgeKV data

We can use EdgeKV to distribute our configuration data across the edge. This tool enables us to store data associated with a key, then retrieve that data from within EdgeWorkers code. In this example, we will associate configuration data with each hostname, then add that data to an EdgeKV database. We’ll then store the configuration data in EdgeKV as a value, and use the hostname as the key to find that value.

First, we’ll need to ensure a valid naming convention for the keys we intend to use, since keys can only contain the characters 0–9, a–z, A–Z, - (hyphen), and _ (underscore).  We can’t use a direct hostname for our key — such as “www.application.com” — because a period violates the naming convention. 

To preemptively avoid invalid character issues, we can simply replace any disallowed characters with an underscore. For example, “www.hostname.com” would become “www_hostname_com” when using our key as a workaround.

For this example, we’ll use two hostnames that correspond to two different applications with different owners inside a single enterprise. The first application has page caching disabled and Image & Video Manager enabled, while the second application has page caching enabled and Image & Video Manager disabled. This corresponds to the following two EdgeKV keys and values:

  • Disable page caching and enable Image & Video Manager
    • EdgeKV key: www_hostname1_com
    • File (www.hostname1.com.json)
  {
   "flags": {
       "PAGE_CACHING": "false",
       "IM_ENABLED": "true"
   }
}
  • Enable page caching and disable Image & Video Manager

    • EdgeKV key: www_hostname2_com
    • File (www.hostname2.com.json)
  {
   "flags": {
       "PAGE_CACHING": "true",
       "IM_ENABLED": "false"
   }
}

To populate data into EdgeKV, we use the Akamai command-line interface (CLI). Refer to the comprehensive CLI documentation for instructions on how to install the CLI and the EdgeWorkers package. You’ll also find an overview of commands to help manage EdgeWorkers and EdgeKV. 

The following command will create an item in EdgeKV. It writes the data to the Akamai staging environment using the default namespace, the feature flags for the groupId, the hostname for the ItemId or key, and the JSON file containing the configuration flags for the value. Read the documentation for more details about the EdgeKV data model.

  $ akamai edgekv write jsonfile staging default feature-flags www_hostname1_com www.hostname1.com.json
  $ akamai edgekv write jsonfile staging default feature-flags www_hostname2_com www.hostname2.com.json

Configuration lookup and flag set code

Here’s the full code:

  import { EdgeKV } from './edgekv.js';
 
// set all PMUSER variables with a common prefix,
// avoiding accidental collisions with existing variables
const PMUSER_VAR_PREFIX = "PMUSER_FLAGS_"
 
// Initialize EdgeKV library
const edgeKv = new EdgeKV({namespace: "default", group: "feature-flags"});
 
const INVALID_KEY_PATTERN = /[^-_a-zA-Z0-9]/g
 
export async function onClientRequest(request) {
   // Get EdgeKV key from request.
   // Incoming hostname is used as the key.
   // Characters that are not valid in an EdgeKV key are replaced with an underscore.
   let key = request.host.replace(INVALID_KEY_PATTERN, "_");
 
   // Lookup hostname's configuration data from EdgeKV
   let data = await edgeKv.getJson({ item: key });
 
   // If configuration object exists, loop through flags and set Property Manager variables
   if (data && data.flags) {
       Object.entries(data.flags).forEach(([name,value])=>{
           request.setVariable(`${PMUSER_VAR_PREFIX}${name}`, value)
       })
   }
}

Configuration lookup and flag set code, explained

Implementing the feature flag logic in EdgeWorkers requires only a few lines of JavaScript code.

1. Import the required modules

  import { EdgeKV } from './edgekv.js';

First, we import Akamai’s edgekv.js helper library that simplifies working with EdgeKV. You can find documentation and a download for the helper library at the helper library download page.

2. Contact the database

  const edgeKv = new EdgeKV({namespace: "default", group: "feature-flags"});

Use an EdgeKV constructor to instantiate a new EdgeKV object that passes the namespace and group containing the data. The namespace and group should be the same values used earlier to insert the items to EdgeKV. Note that this example uses the default namespace for testing purposes. 

Before sending the request to cache or back to origin, we run our EdgeWorkers on every request as soon as one is received. The goal is to control CDN features and use the onClientRequest stage to ensure that our EdgeWorkers runs before any other behaviors. You can learn more about the EdgeWorkers event model and OnClientRequest in the EdgeWorkers event model documentation.

3. Replace the data

  let key = request.host.replace(INVALID_KEY_PATTERN, "_");

Here, we convert the incoming hostname into the corresponding EdgeKV key. 

4. Grab the data from the database

  let data = await edgeKv.getJson({ item: key });

Here, we read data from EdgeKV using the getJson function provided by the edgekv.js helper library. This function executes asynchronously and returns a promise. The keyword “await” forces the JavaScript code to wait until that promise returns its result. 

We then set the data variable with the JSON feature flag configuration item for the given hostname. Items can also be read from EdgeKV as a text string. Both of the getter functions are explained in detail in the helper library documentation

5. Loop through the data and set variables based on it

  if (data && data.flags) {
       Object.entries(data.flags).forEach(([name,value])=>{
           request.setVariable(`${PMUSER_VAR_PREFIX}${name}`, value)
       })
   }

Finally, we iterate through all the flags defined in the configuration object, and set each value to a Property Manager variable. These variables are prefixed with “PMUSER_FLAGS_” to prevent accidental collisions with other Property Manager variables that can be used within the Property Manager configuration. This functionality is described in more detail in the documentation.

Tailored web content delivered

If you’re ready to offer users content tailored to their respective market, read the EdgeKV and EdgeWorkers documentation to learn more about what both products can do for your business.

Learn more

Once you’re up and running with EdgeKV and EdgeWorkers, you can package and run each code sample discussed above by following the steps outlined in the EdgeWorkers Management application. Find the additional step required to load the configuration data into EdgeKV in this CLI documentation.



Akamai Wave Blue

Written by

Philip McGuinness

November 22, 2022

Akamai Wave Blue

Written by

Philip McGuinness

Philip McGuinness is a Senior Technical Solutions Architect at Akamai Technologies.