The Traffic Management API

The Internet domain name system (DNS) is a distributed system that allows computer programs to issue queries about domain names, to which the DNS returns one or more answers. The most common use of the DNS is to convert hostnames, such as www.customer.com, into IP addresses, which identify a particular computer at a particular place in the Internet.

In the most traditional use of the DNS, the answers returned for a query are static: they’re typed into a configuration file by a person, and change only when someone changes the file.

A dynamic DNS system returns answers that are computed on the fly, and can vary from query to query. A typical use is to return the IP address of a server that’s assigned dynamically via DHCP, and can change from time to time, as is common with most home Internet connections.

Akamai’s GTM system is a dynamic DNS system; it manages traffic to your data centers by choosing the best answers, from moment to moment, to return to client nameservers in response to their queries about GTM domains.

Getting Started

The basic building block of a Traffic Management configuration is a Domain. DNS forms a tree-structured namespace. In this list of domain names:

  • com
  • customer.com
  • sales.customer.com

each item is a domain, and each domain is also a subdomain of the one above it in the list. In Akamai’s GTM system, the term "domain" is used in a slightly restricted sense. A GTM domain is a DNS domain, whose name usually ends in .akadns.net. There are a number of attributes that are specified at the GTM domain level; the most important one, perhaps, being Luna access control. Anyone with permission to edit a GTM domain has permission to modify or delete any of the properties (subdomains) within that domain.

For this guide, we’ll walk through setting up a new domain, example.akadns.net. We’ll start of by creating our new domain, and we’ll build on it as we go.

PUT /config-gtm/v1/domains/example.akadns.net HTTP/1.1
Accept: application/json
Content-type: application/json
Content-Length: 173

{
    "name": "example.akadns.net",
    "type": "weighted",
    "emailNotificationList": ["our.admin@example.com"],
    "modificationComments": "New Traffic Management domain."
}

This call creates a weighted domain named example.akadns.net. It also specifies that our.admin@example.com will be sent an email for each change the Traffic Management system processes, as well as other notifications (propagation progress, validation or error messages, etc). The system confirms the domain creation with the HTTP 201 CREATED status code, and returns a full representation of the domain:

HTTP/1.1 201 Created
Date: Mon, 04 Aug 2014 15:30:39 GMT
Content-Type: application/vnd.config-gtm.v1.0+json;charset=UTF-8
{
    "resource": {
        "cidrMaps": [],
        "datacenters": [],
        "defaultErrorPenalty": 75,
        "defaultSslClientCertificate": null,
        "defaultSslClientPrivateKey": null,
        "defaultTimeoutPenalty": 25,
        "emailNotificationList": [ "our.admin@example.com" ],
        "geographicMaps": [],
        "lastModified": "2014-08-04T15:30:40.057+0000",
        "lastModifiedBy": "admin",
        "loadFeedback": false,
        "loadImbalancePercentage": null,
        "modificationComments": "New Traffic Management domain.",
        "name": "example.akadns.net",
        "properties": [],
        "resources": [],
        "status": {
            "changeId": "abb94136-dd94-4779-bfb0-fcfac67fb843",
            "message": "Change Pending",
            "passingValidation": true,
            "propagationStatus": "PENDING",
            "propagationStatusDate": "2014-08-04T15:30:40.057+0000"
        },
        "type": "weighted"
    },
    "status": {
        "changeId": "abb94136-dd94-4779-bfb0-fcfac67fb843",
        "message": "Change Pending",
        "passingValidation": true,
        "propagationStatus": "PENDING",
        "propagationStatusDate": "2014-08-04T15:30:40.057+0000"
    }
}

You’ll see that the server has filled in quite a few fields with default values, such as defaultErrorPenalty and defaultTimeoutPenalty, among others.

The domain types that can be chosen are determined by your contract; the type also places a restriction on what type of properties can be created under the domain. The following table lists each domain type, each column below the type indicates whether the corresponding property type can be created:

  failover-only static weighted basic full
failover
qtr
geographic
cidrmapping
asmapping
weighted-round-robin
weighted-hashed
weighted-round-robin-with-load-feedback
performance

That’s a good start, but the domain is still incomplete. It needs at least two Datacenters defined, and at least one Property before it is considered complete and ready for use. Let’s create two datacenters for our domain, starting with our Winterfell data center:

POST /config-gtm/v1/domains/example.akadns.net/datacenters HTTP/1.1
Accept: application/json
Content-type: application/json
Content-Length: 145

{
    "city": "Downpatrick",
    "continent": "EU",
    "country": "GB",
    "latitude": 54.367,
    "longitude": -5.582,
    "nickname": "Winterfell"
}

The first data center is created by a POST to the /config-gtm/v1/domains/example.akadns.net/datacenters collection. The system assigns a datacenterId to this data center which is included in two places: as part of the response in the Location header, and as a field in the data center’s JSON representation:

HTTP/1.1 201 Created
Date: Mon, 04 Aug 2014 15:49:08 GMT
Location: /config-gtm/v1/domains/example.akadns.net/datacenters/3131
Transfer-Encoding: chunked
Content-Type: application/vnd.config-gtm.v1.0+json;charset=UTF-8

{
    "resource": {
        "city": "Downpatrick",
        "cloneOf": null,
        "continent": "EU",
        "country": "GB",
        "datacenterId": 3131,
        "defaultLoadObject": null,
        "latitude": 54.367,
        "longitude": -5.582,
        "nickname": "Winterfell",
        "stateOrProvince": null,
        "virtual": true
    },
    "status": {
        "changeId": "0a580f0a-d585-4fc0-a3ff-47c79e8fd7fc",
        "message": "Change Pending",
        "passingValidation": true,
        "propagationStatus": "PENDING",
        "propagationStatusDate": "2014-08-04T15:49:10.111+0000"
    }
}

The datacenterId is important, as it’s referenced by many other entities across the domain. Now let’s add the second data center:

POST /config-gtm/v1/domains/example.akadns.net/datacenters HTTP/1.1
Accept: application/json
Content-type: application/json
Content-Length: 248

{
    "city": "Snæfellsjökull",
    "continent": "EU",
    "country": "IS",
    "latitude": 64.808,
    "longitude": -23.776,
    "nickname": "Frostfangs"
}

That data center was assigned the datacenterId of 3131, which now gives us the minimum for a valid domain:

GET /config-gtm/v1/domains/example.akadns.net/datacenters
Content-Type: application/vnd.config-gtm.v1.0+json;charset=UTF-8

{
    "items": [
        {
            "city": "Downpatrick",
            "cloneOf": null,
            "continent": "EU",
            "country": "GB",
            "datacenterId": 3131,
            "defaultLoadObject": {
                "loadObject": null,
                "loadObjectPort": 0,
                "loadServers": null
            },
            "latitude": 54.367,
            "longitude": -5.582,
            "nickname": "Winterfell",
            "stateOrProvince": null,
            "virtual": true
        },
        {
            "city": "Snæfellsjökull",
            "cloneOf": null,
            "continent": "EU",
            "country": "IS",
            "datacenterId": 3132,
            "defaultLoadObject": {
                "loadObject": null,
                "loadObjectPort": 0,
                "loadServers": null
            },
            "latitude": 64.808,
            "longitude": -23.776,
            "nickname": "Frostfangs",
            "stateOrProvince": null,
            "virtual": true
        }
    ]
}

The last piece is a Property, or subdomain, of the example.akadns.net domain. We’ll create a property origin, as a weighted round-robin load balanced property with a 50/50 split:

PUT /config-gtm/v1/domains/example.akadns.net/properties/origin HTTP/1.1
Content-type: application/json
Accept: application/json
Content-Length: 534

{
    "name": "origin",
    "handoutMode": "normal",
    "failoverDelay" : 0,
    "failbackDelay" : 0,
    "trafficTargets": [
        {
            "datacenterId": 3131,
            "enabled": true,
            "servers": [ "1.2.3.5" ],
            "weight": 50.0
        },
        {
            "datacenterId": 3132,
            "enabled": true,
            "servers": [ "1.2.3.4" ],
            "weight": 50.0
        }
    ],
    "type": "weighted-round-robin",
    "scoreAggregationType": "mean"
}

This very basic setup splits requests evenly between our Winterfell data center (datacenterId=3131) and our Frostfangs data center (datacenterId=3132). One thing we’d like to change is that we would like Traffic Management only to hand out IPs that are “alive”, so we should specify a Liveness Test which Traffic Management’s servermonitors can run to determine liveness:

PUT /config-gtm/v1/domains/example.akadns.net/properties/origin HTTP/1.1
Host: iamakamai.qaextranet.akamai.com
Content-type: application/json
Accept: application/json
Content-Length: 982

{
    "name": "origin",
    "handoutMode": "normal",
    "failoverDelay" : 0,
    "failbackDelay" : 0,
    "trafficTargets": [
        {
            "datacenterId": 3131,
            "enabled": true,
            "servers": [ "1.2.3.5" ],
            "weight": 50.0
        },
        {
            "datacenterId": 3132,
            "enabled": true,
            "servers": [ "1.2.3.4" ],
            "weight": 50.0
        }
    ],
    "type": "weighted-round-robin",
    "scoreAggregationType": "mean",
    "livenessTests": [
        {
            "disableNonstandardPortWarning": false,
            "hostHeader": "foo.example.com",
            "httpError3xx": true,
            "httpError4xx": true,
            "httpError5xx": true,
            "name": "health-check",
            "testInterval": 60,
            "testObject": "/status",
            "testObjectPort": 80,
            "testObjectProtocol": "HTTP",
            "testTimeout": 25.0
        }
    ]
}

With this configuration, servermonitors assigned to your domain test each IP address every 60 seconds (testInterval) by running the equivalent of:

curl -H "Host: foo.example.com" http://1.2.3.5/status

The servermonitor treats 300s, 400s and 500s as errors (controlled by the httpError3xx, httpError4xx, httpError3xx settings, respectively); Test agents also time out tests after 25 seconds (testTimeout);

API Versioning

In the examples above, you may have noticed that the return type is application/vnd.config-gtm.v1.0+json. This API supports three types at the present time:

  • application/json
  • application/vnd.config-gtm.v1.0+json
  • application/vnd.config-gtm.v1.1+json

application/json and application/vnd.config-gtm.v1.0+json are synonymous with each other and can be used interchangeably. This approach allows the service to evolve over time. New versions may be introduced, resulting in a minor incremental changes to the version number (e.g., v1.2, v1.3, and so on).

Note that application/json is always synonymous with application/vnd.config-gtm.v1.0+json, regardless of how many versions are added over time. Clients may chose to adopt the new resource versions, or stay on the initial v1.0 version until the need arises to upgrade. It is still recommended that all clients specify the exact version of the representation:

Accept: application/vnd.config-gtm.v1.0+json

API Hypermedia

The API’s data objects feature embedded link relations that provide URL paths that allow direct access to each object. For example, items within a list of domains feature link relations such as the following, where the href responds to a GET request, and a rel of self indicates that it identifies the unique object.

"links": [
    {
        "href": "/config-gtm/v1/domains/example.akadns.net",
        "rel": "self"
    }
],

Last modified: 12/12/2016