Document API with Literate Coffeescript
This commit is contained in:
parent
3cfc1927fa
commit
d184528312
|
@ -1,20 +1,12 @@
|
|||
/*
|
||||
* api
|
||||
* cylonjs.com
|
||||
*
|
||||
* Copyright (c) 2013 The Hybrid Group
|
||||
* Licensed under the Apache 2.0 license.
|
||||
*/
|
||||
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
var express, namespace;
|
||||
|
||||
express = require('express.io');
|
||||
|
||||
namespace = require('node-namespace');
|
||||
|
||||
namespace("Api", function() {
|
||||
namespace('Api', function() {
|
||||
return this.Server = (function() {
|
||||
var master;
|
||||
|
||||
|
@ -55,34 +47,36 @@
|
|||
return _results;
|
||||
})());
|
||||
});
|
||||
this.server.get("/robots/:robotid", function(req, res) {
|
||||
return master.findRobot(req.params.robotid, function(err, robot) {
|
||||
this.server.get("/robots/:robotname", function(req, res) {
|
||||
return master.findRobot(req.params.robotname, function(err, robot) {
|
||||
return res.json(err ? err : robot.data());
|
||||
});
|
||||
});
|
||||
this.server.get("/robots/:robotid/devices", function(req, res) {
|
||||
return master.findRobot(req.params.robotid, function(err, robot) {
|
||||
this.server.get("/robots/:robotname/devices", function(req, res) {
|
||||
return master.findRobot(req.params.robotname, function(err, robot) {
|
||||
return res.json(err ? err : robot.data().devices);
|
||||
});
|
||||
});
|
||||
this.server.get("/robots/:robotid/devices/:deviceid", function(req, res) {
|
||||
var deviceid, robotid, _ref;
|
||||
_ref = [req.params.robotid, req.params.deviceid], robotid = _ref[0], deviceid = _ref[1];
|
||||
return master.findRobotDevice(robotid, deviceid, function(err, device) {
|
||||
this.server.get("/robots/:robotname/devices/:devicename", function(req, res) {
|
||||
var devicename, params, robotname;
|
||||
params = [req.params.robotname, req.params.devicename];
|
||||
robotname = params[0], devicename = params[1];
|
||||
return master.findRobotDevice(robotname, devicename, function(err, device) {
|
||||
return res.json(err ? err : device.data());
|
||||
});
|
||||
});
|
||||
this.server.get("/robots/:robotid/devices/:deviceid/commands", function(req, res) {
|
||||
var deviceid, robotid, _ref;
|
||||
_ref = [req.params.robotid, req.params.deviceid], robotid = _ref[0], deviceid = _ref[1];
|
||||
return master.findRobotDevice(robotid, deviceid, function(err, device) {
|
||||
this.server.get("/robots/:robotname/devices/:devicename/commands", function(req, res) {
|
||||
var devicename, params, robotname;
|
||||
params = [req.params.robotname, req.params.devicename];
|
||||
robotname = params[0], devicename = params[1];
|
||||
return master.findRobotDevice(robotname, devicename, function(err, device) {
|
||||
return res.json(err ? err : device.data().commands);
|
||||
});
|
||||
});
|
||||
this.server.post("/robots/:robot/devices/:device/commands/:command", function(req, res) {
|
||||
var commandid, deviceid, key, params, robotid, value, _ref;
|
||||
params = [req.params.robot, req.params.device, req.params.command];
|
||||
robotid = params[0], deviceid = params[1], commandid = params[2];
|
||||
this.server.post("/robots/:robot/devices/:device/commands/:commandname", function(req, res) {
|
||||
var commandname, devicename, key, params, robotname, value, _ref;
|
||||
params = [req.params.robotname, req.params.devicename, req.params.commandname];
|
||||
robotname = params[0], devicename = params[1], commandname = params[2];
|
||||
params = [];
|
||||
if (typeof req.body === 'object') {
|
||||
_ref = req.body;
|
||||
|
@ -91,36 +85,38 @@
|
|||
params.push(value);
|
||||
}
|
||||
}
|
||||
return master.findRobotDevice(robotid, deviceid, function(err, device) {
|
||||
return master.findRobotDevice(robotname, devicename, function(err, device) {
|
||||
var result;
|
||||
if (err) {
|
||||
return res.json(err);
|
||||
}
|
||||
result = device[commandid].apply(device, params);
|
||||
result = device[commandname].apply(device, params);
|
||||
return res.json({
|
||||
result: result
|
||||
});
|
||||
});
|
||||
});
|
||||
this.server.get("/robots/:robotid/connections", function(req, res) {
|
||||
return master.findRobot(req.params.robotid, function(err, robot) {
|
||||
this.server.get("/robots/:robotname/connections", function(req, res) {
|
||||
return master.findRobot(req.params.robotname, function(err, robot) {
|
||||
return res.json(err ? err : robot.data().connections);
|
||||
});
|
||||
});
|
||||
this.server.get("/robots/:robot/connections/:connection", function(req, res) {
|
||||
var connectionid, robotid, _ref;
|
||||
_ref = [req.params.robot, req.params.connection], robotid = _ref[0], connectionid = _ref[1];
|
||||
return master.findRobotConnection(robotid, connectionid, function(err, connection) {
|
||||
var connectionname, params, robotname;
|
||||
params = [req.params.robot, req.params.connection];
|
||||
robotname = params[0], connectionname = params[1];
|
||||
return master.findRobotConnection(robotname, connectionname, function(err, connection) {
|
||||
return res.json(err ? err : connection.data());
|
||||
});
|
||||
});
|
||||
this.server.get("/robots/:robotid/devices/:deviceid/events", function(req, res) {
|
||||
this.server.get("/robots/:robotname/devices/:devicename/events", function(req, res) {
|
||||
return req.io.route('events');
|
||||
});
|
||||
return this.server.io.route('events', function(req) {
|
||||
var deviceid, robotid, _ref;
|
||||
_ref = [req.params.robotid, req.params.deviceid], robotid = _ref[0], deviceid = _ref[1];
|
||||
return master.findRobotDevice(robotid, deviceid, function(err, device) {
|
||||
var devicename, params, robotname;
|
||||
params = [req.params.robotname, req.params.devicename];
|
||||
robotname = params[0], devicename = params[1];
|
||||
return master.findRobotDevice(robotname, devicename, function(err, device) {
|
||||
if (err) {
|
||||
req.io.respond(err);
|
||||
}
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
###
|
||||
* api
|
||||
* cylonjs.com
|
||||
*
|
||||
* Copyright (c) 2013 The Hybrid Group
|
||||
* Licensed under the Apache 2.0 license.
|
||||
###
|
||||
|
||||
express = require('express.io')
|
||||
namespace = require 'node-namespace'
|
||||
|
||||
namespace "Api", ->
|
||||
# The Cylon API Server provides an interface to communicate with master class
|
||||
# and retrieve information about the robots being controlled.
|
||||
class @Server
|
||||
master = null
|
||||
|
||||
constructor: (opts = {}) ->
|
||||
@host = opts.host || "127.0.0.1"
|
||||
@port = opts.port || "3000"
|
||||
|
||||
master = opts.master
|
||||
|
||||
@server = express().http().io()
|
||||
@server.set 'name', 'Cylon API Server'
|
||||
@server.use(express.bodyParser())
|
||||
|
||||
@server.get "/*", (req, res, next) ->
|
||||
res.set 'Content-Type', 'application/json'
|
||||
do next
|
||||
|
||||
do @configureRoutes
|
||||
|
||||
@server.listen @port, @host, =>
|
||||
Logger.info "#{@server.name} is listening at #{@host}:#{@port}"
|
||||
|
||||
configureRoutes: ->
|
||||
@server.get "/robots", (req, res) ->
|
||||
res.json (robot.data() for robot in master.robots())
|
||||
|
||||
@server.get "/robots/:robotid", (req, res) ->
|
||||
master.findRobot req.params.robotid, (err, robot) ->
|
||||
res.json if err then err else robot.data()
|
||||
|
||||
@server.get "/robots/:robotid/devices", (req, res) ->
|
||||
master.findRobot req.params.robotid, (err, robot) ->
|
||||
res.json if err then err else robot.data().devices
|
||||
|
||||
@server.get "/robots/:robotid/devices/:deviceid", (req, res) ->
|
||||
[robotid, deviceid] = [req.params.robotid, req.params.deviceid]
|
||||
master.findRobotDevice robotid, deviceid, (err, device) ->
|
||||
res.json if err then err else device.data()
|
||||
|
||||
@server.get "/robots/:robotid/devices/:deviceid/commands", (req, res) ->
|
||||
[robotid, deviceid] = [req.params.robotid, req.params.deviceid]
|
||||
master.findRobotDevice robotid, deviceid, (err, device) ->
|
||||
res.json if err then err else device.data().commands
|
||||
|
||||
@server.post "/robots/:robot/devices/:device/commands/:command", (req, res) ->
|
||||
params = [req.params.robot, req.params.device, req.params.command]
|
||||
[robotid, deviceid, commandid] = params
|
||||
|
||||
params = []
|
||||
if typeof req.body is 'object'
|
||||
params.push(value) for key, value of req.body
|
||||
|
||||
master.findRobotDevice robotid, deviceid, (err, device) ->
|
||||
if err then return res.json err
|
||||
result = device[commandid](params...)
|
||||
res.json result: result
|
||||
|
||||
@server.get "/robots/:robotid/connections", (req, res) ->
|
||||
master.findRobot req.params.robotid, (err, robot) ->
|
||||
res.json if err then err else robot.data().connections
|
||||
|
||||
@server.get "/robots/:robot/connections/:connection", (req, res) ->
|
||||
[robotid, connectionid] = [req.params.robot, req.params.connection]
|
||||
|
||||
master.findRobotConnection robotid, connectionid, (err, connection) ->
|
||||
res.json if err then err else connection.data()
|
||||
|
||||
@server.get "/robots/:robotid/devices/:deviceid/events", (req, res) ->
|
||||
req.io.route 'events'
|
||||
|
||||
@server.io.route 'events', (req) ->
|
||||
[robotid, deviceid] = [req.params.robotid, req.params.deviceid]
|
||||
|
||||
master.findRobotDevice robotid, deviceid, (err, device) ->
|
||||
req.io.respond(err) if err
|
||||
device.on 'update', (data) ->
|
||||
req.io.emit 'update', { data: data }
|
|
@ -5,14 +5,19 @@ with the currently running robots.
|
|||
|
||||
First of all, let's make sure we're running in ECMAScript 5's [strict mode][].
|
||||
|
||||
[strict mode]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
|
||||
|
||||
'use strict';
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
Our server needs to primarily respond to HTTP requests with JSON responses, but
|
||||
also needs to handle a WebSocket connection to listen for events. To accomodate
|
||||
both of these requirements, we're going to use [express.io][].
|
||||
|
||||
[express.io]: http://express-io.org
|
||||
|
||||
express = require 'express.io'
|
||||
|
||||
`express.io` integrates some [socket.io][] functionality on top of the popular
|
||||
|
@ -20,9 +25,14 @@ both of these requirements, we're going to use [express.io][].
|
|||
types of connections, and also use Express-style routing to resolve to
|
||||
a Socket.IO connection.
|
||||
|
||||
[socket.io]: http://socket.io
|
||||
[express]: http://expressjs.com
|
||||
|
||||
To keep in line with the rest of Cylon, we'll also be namespacing our API server
|
||||
with the [node-namespace][] module.
|
||||
|
||||
[node-namespace]: https://github.com/kaero/node-namespace
|
||||
|
||||
namespace = require 'node-namespace'
|
||||
|
||||
## Namespacing
|
||||
|
@ -90,11 +100,136 @@ Next up, we run a function to define all our routes (you'll see it in a minute)
|
|||
|
||||
And finally, we start our server, announcing so via the Logger.
|
||||
|
||||
@server.listen @port, @host, =>
|
||||
Logger.info "#{@server.name} is listening at #{@host}:#{@port}"
|
||||
@server.listen @port, @host, =>
|
||||
Logger.info "#{@server.name} is listening at #{@host}:#{@port}"
|
||||
|
||||
[strict mode]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
|
||||
[express.io]: http://express-io.org
|
||||
[express]: http://expressjs.com
|
||||
[socket.io]: http://socket.io
|
||||
[jnode-namespace]: https://github.com/kaero/node-namespace
|
||||
## Routes
|
||||
|
||||
We'll use the previously referenced `@configureRoutes` function to define our
|
||||
server's routes.
|
||||
|
||||
configureRoutes: ->
|
||||
|
||||
### GET /robots
|
||||
|
||||
Our first route returns all the Robots the master class knows about in JSON
|
||||
format.
|
||||
|
||||
@server.get "/robots", (req, res) ->
|
||||
res.json (robot.data() for robot in master.robots())
|
||||
|
||||
### GET /robots/:robotname
|
||||
|
||||
Given a robot's name, returns JSON information about the requested Robot:
|
||||
|
||||
@server.get "/robots/:robotname", (req, res) ->
|
||||
master.findRobot req.params.robotname, (err, robot) ->
|
||||
res.json if err then err else robot.data()
|
||||
|
||||
### GET /robots/:robotname/devices
|
||||
|
||||
Given a robot's name, returns JSON information about the devices belonging to
|
||||
the requested Robot:
|
||||
|
||||
@server.get "/robots/:robotname/devices", (req, res) ->
|
||||
master.findRobot req.params.robotname, (err, robot) ->
|
||||
res.json if err then err else robot.data().devices
|
||||
|
||||
### GET /robots/:robotname/devices/:devicename
|
||||
|
||||
Given the names of a device and the robot it belongs to, returns data on the
|
||||
specified device.
|
||||
|
||||
@server.get "/robots/:robotname/devices/:devicename", (req, res) ->
|
||||
params = [req.params.robotname, req.params.devicename]
|
||||
[robotname, devicename] = params
|
||||
|
||||
master.findRobotDevice robotname, devicename, (err, device) ->
|
||||
res.json if err then err else device.data()
|
||||
|
||||
### GET /robots/:robotname/devices/:devicename/commands
|
||||
|
||||
Given the names of a device and the robot it belongs to, returns all commands
|
||||
available for the specified device.
|
||||
|
||||
@server.get "/robots/:robotname/devices/:devicename/commands", (req, res) ->
|
||||
params = [req.params.robotname, req.params.devicename]
|
||||
[robotname, devicename] = params
|
||||
|
||||
master.findRobotDevice robotname, devicename, (err, device) ->
|
||||
res.json if err then err else device.data().commands
|
||||
|
||||
### POST /robots/:robotname/devices/:devicename/commands/:commandname
|
||||
|
||||
Given a robot name, device name, and command name, executes a robot's command
|
||||
and returns the result.
|
||||
|
||||
@server.post "/robots/:robot/devices/:device/commands/:commandname", (req, res) ->
|
||||
|
||||
params = [
|
||||
req.params.robotname,
|
||||
req.params.devicename,
|
||||
req.params.commandname
|
||||
]
|
||||
|
||||
[robotname, devicename, commandname] = params
|
||||
|
||||
This parses params from the request body into values that can be used while
|
||||
calling the command, if params have been supplied.
|
||||
|
||||
params = []
|
||||
if typeof req.body is 'object'
|
||||
params.push(value) for key, value of req.body
|
||||
|
||||
Runs the command on the Robot's device, passing in params as provided.
|
||||
|
||||
master.findRobotDevice robotname, devicename, (err, device) ->
|
||||
if err then return res.json err
|
||||
result = device[commandname](params...)
|
||||
res.json result: result
|
||||
|
||||
### GET /robots/:robotname/connections
|
||||
|
||||
Given a robot's name, returns JSON information about the connections belonging
|
||||
to the requested Robot:
|
||||
|
||||
@server.get "/robots/:robotname/connections", (req, res) ->
|
||||
master.findRobot req.params.robotname, (err, robot) ->
|
||||
res.json if err then err else robot.data().connections
|
||||
|
||||
### GET /robots/:robotname/connections/:connectionname
|
||||
|
||||
Given a robot's name, returns JSON information about the connections belonging
|
||||
to the requested Robot:
|
||||
|
||||
@server.get "/robots/:robot/connections/:connection", (req, res) ->
|
||||
params = [req.params.robot, req.params.connection]
|
||||
[robotname, connectionname] = params
|
||||
|
||||
master.findRobotConnection robotname, connectionname, (err, connection) ->
|
||||
res.json if err then err else connection.data()
|
||||
|
||||
### GET /robots/:robotname/devices/:devicename/events
|
||||
|
||||
Routes to a Socket.IO route to handle WebSockets connections requesting updates
|
||||
on device events.
|
||||
|
||||
@server.get "/robots/:robotname/devices/:devicename/events", (req, res) ->
|
||||
req.io.route 'events'
|
||||
|
||||
### WS_GET /events
|
||||
|
||||
A Socket.IO route to handle updating clients whenever a device sends
|
||||
an 'update' event.
|
||||
|
||||
Listens for the 'update' event on a particular Robot's device, and whenever the
|
||||
device sends the 'update' event, passes the data along to the client.
|
||||
|
||||
@server.io.route 'events', (req) ->
|
||||
params = [req.params.robotname, req.params.devicename]
|
||||
[robotname, devicename] = params
|
||||
|
||||
master.findRobotDevice robotname, devicename, (err, device) ->
|
||||
req.io.respond(err) if err
|
||||
device.on 'update', (data) ->
|
||||
req.io.emit 'update', { data: data }
|
||||
|
|
Loading…
Reference in New Issue