Thursday, February 3, 2011

Growing a REST API, Part 2 of 2

OK, let's jump back into the fray here with part 2 (part 1 is here) of our discussion on the REST API for the Vyatta Appliance thingy. Now, we've already covered the API up to and including the Configuration mode. And found out that commands are relatively simple to construct. What's left you ask? The operational side of things and the weird red headed step-child interface: App mode.

Without further ado then...



Operation mode:
Op mode as you remember is focused on providing status data related to the operation of the router, but does not change the state of the system. The operation mode is distinct from the configuration side in other ways as well. For one, commands have different life cycles--which means a command may never return (think ping). Another difference is that responses can be quite large (such as viewing a syslog). For this reason the REST API relationship with this mode is completely different.

Down in the engine room of the server, where the operational mode request is received, the server starts a process devoted to this command, manages this process and makes the output available for subsequent fetches. The command initiating the response however, returns immediately with no data other than a url location where data associated with this process will be found. In this way, the command can be non-blocking, but requires a minimum of 2 requests to start getting data associated with the command.

Commands available in op mode are:

#initiate an op mode command
POST rest/op/command

#get status of your op mode commands
GET rest/op
#get status of a specific op mode command
GET rest/op/token

#get output from your command
GET rest/op/command

#kill process and delete resources associated with command
DELETE rest/op/token

Just a note. When retrieving data associated with the command output, the GET model is a feed forward type fetch. In other words you move the read pointer forward on each fetch of data.

Even with the process management, this really is a simpler interaction model than on the conf mode side of the Vyatta REST family. Using the commands we just learned a typical sequence follows--the client POSTs a command, fetches output via recursive GETs, and finally DELETE the comand. The only other option's available are to view the currently running processes, and to get information about a specific command (but not process).




And the request/response headers and bodies look like with a simple ping command are:


Start the process.
POST /rest/op/ping/10.3.0.1 HTTP/1.1
  User-Agent: curl/7.21.0 (i486-pc-linux-gnu) libcurl/7.21.0 
OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6
Host: 10.3.0.104
Accept: */*
authorization: Basic dnlhdHRhOnZ5YXR0YQ==
content-length:0

HTTP/1.1 201 Created
Content-Type: application/json
Location: rest/op/7EAC25ACB6F7EC7F
Vyatta-Specification-Version: 0.2
Cache-Control: no-cache
Transfer-Encoding: chunked
Date: Thu, 27 Jan 2011 23:26:37 GMT
Server: lighttpd/1.4.28

Start fetching data.
GET /rest/op/7EAC25ACB6F7EC7F HTTP/1.1
User-Agent: curl/7.21.0 (i486-pc-linux-gnu) libcurl/7.21.0 
  OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6
Host: 10.3.0.104
Accept: */*
authorization: Basic dnlhdHRhOnZ5YXR0YQ==
content-length:0

HTTP/1.1 200 OK
Content-Type: text/plain
Vyatta-Specification-Version: 0.2
Cache-Control: no-cache
Content-Length: 5912
Date: Thu, 27 Jan 2011 23:28:20 GMT
Server: lighttpd/1.4.28

PING 10.3.0.1 (10.3.0.1) 56(84) bytes of data.
64 bytes from 10.3.0.1: icmp_req=1 ttl=64 time=0.583 ms
64 bytes from 10.3.0.1: icmp_req=2 ttl=64 time=0.573 ms
64 bytes from 10.3.0.1: icmp_req=3 ttl=64 time=0.576 ms
64 bytes from 10.3.0.1: icmp_req=4 ttl=64 time=0.616 ms

Check the process status.
GET /rest/op/7EAC25ACB6F7EC7F HTTP/1.1
User-Agent: curl/7.21.0 (i486-pc-linux-gnu) libcurl/7.21.0 
  OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6
Host: 10.3.0.104
Accept: */*
authorization: Basic dnlhdHRhOnZ5YXR0YQ==
content-length:0

HTTP/1.1 200 OK
Content-Type: application/json
Vyatta-Specification-Version: 0.2
Cache-Control: no-cache
Content-Length: 356
Date: Thu, 27 Jan 2011 23:31:36 GMT
Server: lighttpd/1.4.28

{
  "process": [
    {
      "username": "vyatta",
      "start-time": "1296171074",
      "last-update": "16",
      "id": "7EAC25ACB6F7EC7F",
      "command": "ping 10.3.0.1"
    }
  ]
}


Finally, release the process (and its resources).
DELETE /rest/op/7EAC25ACB6F7EC7F HTTP/1.1
User-Agent: curl/7.21.0 (i486-pc-linux-gnu) libcurl/7.21.0 
  OpenSSL/0.9.8o zlib/1.2.3.4 libidn/1.15 libssh2/1.2.6
Host: 10.3.0.104
Accept: */*
authorization: Basic dnlhdHRhOnZ5YXR0YQ==
content-length:0

HTTP/1.1 200 OK
Content-Type: application/json
Vyatta-Specification-Version: 0.2
Cache-Control: no-cache
Content-Length: 21
Date: Thu, 27 Jan 2011 23:29:48 GMT
Server: lighttpd/1.4.28

{
  "message": " "
}


You are responsible for removing the process you initiated on the router. Too many open processes will eat into your disk space, CPU and process space, cause indigestion, and mild flu symptoms. It's a good idea to perform basic housekeeping from time to time.

It's worth noting that commands requiring user input are currently not supported--you will need to know which commands these are (there are a few, such as reboot). A final note, that processes will be removed on system restart (as opposed to configuration mode where these resources remain after reboot).

APP Mode:
The red-haired step-child. Out of the box the App Mode does nothing.

What it does provide is a framework for you, the developer, to install pieces of code on the server and access these through the same framework as operational and configurational mode.

Code can be dropped into /opt/vyatta/share/template-app/templates/[YOUR-HANDLER-PATH-GOES-HERE].

And correspondingly the URL to access this command is:

GET|POST https://[IP]/rest/app/[YOUR-HANDLER]

On the vyatta appliance thingy you'll see some examples already at this location you can look at to get an idea of how things are being done. I promise if there's interest I'll go into more detail on this mode and how to do certain things.

But, if you are a developer you need to provide both a piece of code on the server and then use the client to access this code. The good thing is that this type of relationship can open up all kinds of behavior not supported in the configuration or the operational mode side of things.

Examples of stuff you could do in APP mode are perhaps a long pulling client (a hacked push model), or a system to used to record system statistics locally, or a specialized management interface, etc.

Currently the response body is limited to JSON, but this should be extended to include unformatted text.

As the interface is extended the version will be bumped on the release (current version is 0.2).

So, there you have it. An overview of the current state of REST API. Let me know if you have any specific questions--I can dive into these in a future posting.

No comments:

Post a Comment