API Servers in Node.js

Paul Querna
February 29, 2012

Background

In the beginning...

More Stuff!

More and More!

API Servers are hard.


Simple API servers are simple. Anything can work. Node.js, Rails, Django are all great.

Real world API servers evolve into transformative reverse proxies to dozens of services with different scaling properties.

When one backend gets slow, does it take down your entire API server?

How does your API server fetch data from 10 different backends for one view?

API Server Features

Today's Focus

Content Generation

Content Generation: Grown up.

node-elementtree

var et = require('elementtree');

var root = et.Element('sounds');

var meow = new et.SubElement(root, 'meow',
                            {volume: '42', source: 'cats'});

var dctitle = new et.QName('http://purl.org/dc/elements/1.1/','title');

var title = new et.SubElement(root, dctitle);

title.text = "Hello World";

var doc = new et.ElementTree(root);

console.log(doc.write());
        

ElementTree generates correct XML.

<?xml version="1.0" encoding="utf-8"?>
<sounds xmlns:dc="http://purl.org/dc/elements/1.1/">
  <meow source="cats" volume="42"/>
  <dc:title>Hello World</dc:title>
</sounds>
        

Input Validation

node-swiz

Example Swiz Definition

var def = [
  O('Node',
    {
      'fields': [
        F('key', {'val' : new Chain().isString()}),
        F('ip_address_v4', {'val' : new Chain().isIP()}),
        F('name', {'val': new Chain().isString(),
          'filterFrom': ['public']})
      ],
      'plural': 'nodes'
    })
];
        

Example Errors from Swiz

POST ....

{
    "key": "1234",
    "ip_address_v4": "x1.2.0.4"
}

{ key: 'ip_address_v4', parentKeys: [], message: 'Invalid IP' }

Example Swiz Output

{
    "key": "1234",
    "ip_address_v4": "1.2.0.4"
}
<?xml version='1.0' encoding='utf-8'?>
<node>
  <key>1234</key>
  <ip_address_v4>1.2.0.4</ip_address_v4>
</node>

One more thing: Docs

NameDescriptionValidation
monitoring_zones_poll List of monitoring zones to poll from.
  • Array [String]

type The type of check.
  • Immutable

  • String

  • One of (remote.dns, remote.ftp-banner, remote.imap-banner, remote.pop3-banner, remote.smtp-banner, remote.postgresql-banner, remote.telnet-banner, remote.mysql-banner, remote.mssql-banner, remote.ssh, remote.smtp, remote.http, remote.tcp, remote.ping)

details Details specific to the check type.
  • Optional

  • Hash [String,String between 1 and 255 characters long:Optional]

disabled Disables the check.
  • Optional

  • Boolean

label A friendly label for a check.
  • Optional

  • String between 1 and 255 characters long

period The period in seconds for a check. The value must be greater than the minimum period set on your account.
  • Optional

  • Integer

  • Value (30..1800)

target_alias A key in the entity's 'ip_addresses' hash used to resolve this check to an IP address.
  • Optional

  • String between 1 and 64 characters long

target_hostname The hostname this check should target. This parameter is mutually exclusive with target_alias.
  • Optional

  • String between 1 and 255 characters long

target_resolver Determines how to resolve the check target.
  • Optional

  • One of (IPv4, IPv6)

timeout The timeout in seconds for a check. This has to be less than the period.
  • Optional

  • Integer

  • Value (2..1800)

Thank you!