Application structure

Defining your Node.js package

To build a Carbon.io service you start by creating a standard node package:

% tree hello-world
hello-world
├── bin
│   └── HelloService.js
├── lib
│   └── HelloService.js
├── package.json
└── test
    └── HelloServiceTest.js

Your package.json file should include carbon-io:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "name": "hello-world",
  "version": "0.0.1",
  "description": "Hello World API.",
  "main": "./lib/HelloService.js",
  "scripts": {
      "start": "node ./lib/HelloService.js",
      "test": "node ./test"
  },
  "bin": {
      "HelloService": "./bin/HelloService.js"
  },
  "dependencies": {
      "carbon-io": "*"
  }
}

While the carbon-io dependency shown in the above example will always pull in the latest version, you will likely want to pin it to a specific minor version. e.g.:

"carbonio": "0.7.x"

You then install the package dependencies like so:

% cd /path/to/hello-world
% npm install .

Defining your Service

Next you create your app / service. Continuing with the example above, HelloService.js would look something like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
var carbon = require('carbon-io')

var __ = carbon.fibers.__(module)
var _o = carbon.bond._o(module)
var o = carbon.atom.o(module)

__(function() {
  module.exports = o.main({
    _type: carbon.carbond.Service,
    /*
     * implementation...
     */
  })
})

Using __, _o, and o

The preamble requires the main carbon-io package as well and defines the __, _o, and o operators.

1
2
3
4
5
var carbon = require('carbon-io')

var __ = carbon.fibers.__(module)
var _o = carbon.bond._o(module)
var o = carbon.atom.o(module)

The __ operator is used to run this service inside of a Fiber when this module is invoked as the main module from the command line. Carbon.io makes heavy use of Node Fibers to allow for services to be written in a synchronous (as well as asynchronous) style. More details can be found in the documentation for the Carbon.io fibers package.

The _o operator is the name resolver utility used by Carbon.io. It is not used in this example, although it is used commonly, and documented as part of the bond sub-project.

The o operator is part of the Atom sub-project of Carbon.io and is what is used to define Carbon.io components. It is not crucial you understand this deeply at this point but you should eventually read the Atom documentation to understand the Carbon.io component infrastructure, as it is core to Carbon.io.

In our example, we define our top-level component and export it via module.exports. While exporting the component we define is not strictly required if we only plan to use this service as a main module, it is useful to export it so that it can later be required as a library by other components or modules if desired. It should be noted that the component is defined to be an instance of the Service class. This class is the base class used for defining services in carbond and will be described more fully in subsequent sections.

1
2
3
4
5
6
7
8
__(function() {
  module.exports = o.main({
    _type: carbon.carbond.Service,
    /*
     * implementation...
     */
  })
})

Running your Service

Finally, the hello-world application can be invoked from the command line as follows:

% node <path-to-your-app>/lib/HelloService.js
 [Mon Feb 09 2015 21:56:41 GMT-0800 (PST)] INFO: Service starting...
 [Mon Feb 09 2015 21:56:41 GMT-0800 (PST)] INFO: Service listening on port 8888
 [Mon Feb 09 2015 21:56:41 GMT-0800 (PST)] INFO: Service started

For more details on running carbond Services see the documentation on running services from the command line.