A Node.js application framework for building microservices and APIs.

Install Carbon.io

View package on npm

Install the latest stable version of Carbon.io with npm.

        $ npm install carbon-io
      

Hello World

View example on GitHub

With Carbon.io, APIs are defined via Services. A Service is an HTTP server that exposes a JSON REST API and which is defined as a tree of Endpoints. This Service defines a HTTP GET method on an Endpoint called "hello".

        const carbon = require('carbon-io')
const __     = carbon.fibers.__(module)
const o      = carbon.atom.o(module).main

__(function() {
  module.exports = o({
    _type: carbon.carbond.Service,
    port: 8888,
    endpoints : {
      hello: o({
        _type: carbon.carbond.Endpoint,
        get: function(req, res) {
          return { msg: 'Hello, world!' }
        }
      })
    }
  })
})
      

Endpoints & Operations

View example on GitHub

Each Endpoint is made up of Operations, which can formally define request parameters and responses. Operation definitions can use JSON Schemas to automatically validate input parameters and output responses.

        const carbon = require('carbon-io')
const __     = carbon.fibers.__(module)
const o      = carbon.atom.o(module).main

__(function() {
  module.exports = o({
    _type: carbon.carbond.Service,
    port: 8888,
    endpoints : {
      hello: o({
        _type: carbon.carbond.Endpoint,

        get: {
          parameters: {
            who: {
              location: 'query',  // can be query, header, path, or body
              required: false,
              default: 'world',
              schema: { type: 'string' }
            }
          },
          responses: [
            {
              statusCode: 200,
              description: 'Success',
              schema: {
                type: 'object',
                properties: {
                  msg: { type: 'string' }
                },
                required: [ 'msg' ],
                additionalProperties: false
              }
            }
          ],

          service: function(req, res) {
            return { msg: `Hello ${req.parameters.who}!` }
          }
        }
      })
    }
  })
})
      

MongoDB Collections

View example on GitHub

Collections are a high-level abstraction on top of Endpoints that provide a higher-level interface for implementing access to a collection of resources. You can easily implement full database CRUD with virtually no code.

        const carbon = require('carbon-io')
const __     = carbon.fibers.__(module)
const o      = carbon.atom.o(module).main

__(function() {
  module.exports = o({
    _type: carbon.carbond.Service,
    port: 8888,
    dbUri: 'mongodb://localhost:27017/mydb',
    endpoints: {
      articles: o({
        _type: carbon.carbond.mongodb.MongoDBCollection,
        collection: 'articles',
        enabled: { '*': true }
      })
    }
  })
})
      

This supports the following HTTP methods and Endpoints:

/<zipcodes>
POST
GET
PATCH
DELETE
/<zipcodes>/:_id
PUT
GET
PATCH
DELETE

Microservice Chaining

View example on GitHub

Microservices often need to communicate with other microservices. Carbon.io makes it easy to communicate between multiple Services.

This example defines two services:

Artboard 1 Artboard 1 copy
PublicHelloService.js
PrivateHelloService.js
         const carbon = require('carbon-io')
const __     = carbon.fibers.__(module)
const o      = carbon.atom.o(module).main
const _o     = carbon.bond._o(module)

__(function() {
  module.exports = o({
    _type: carbon.carbond.Service,
    port: 8888,
    privateHelloService: _o('http://localhost:9999'),
    
    endpoints : {
      hello: o({
        _type: carbon.carbond.Endpoint,
        
        get: {
          responses: [
            {
              statusCode: 200,
              description: 'Success',
              schema: {
                type: 'object',
                properties: {
                  msg: { type: 'string' }
                },
                required: [ 'msg' ],
                additionalProperties: false
              }
            }
          ],
          
          service: function(req, res) {
            return this.getService().privateHelloService.getEndpoint('hello').get().body
          }
        }

      })
    }

  })
})
      
        const carbon = require('carbon-io')
const __     = carbon.fibers.__(module)
const o      = carbon.atom.o(module).main

__(function() {
  module.exports = o({

    _type: carbon.carbond.Service,
    port: 9999,

    endpoints : {
      hello: o({
        _type: carbon.carbond.Endpoint,
        
        get: {
          responses: [
            {
              statusCode: 200,
              description: "Success",
              schema: {
                type: 'object',
                properties: {
                  msg: { type: 'string' }
                },
                required: [ 'msg' ],
                additionalProperties: false
              }
            }
          ],
          
          service: function(req, res) {
            return { msg: "Hello world!" }
          }
        }

      })
    }

  })
})
      

Authentication & Access Control

View example on GitHub

Every Carbon.io Service can be configured with an Authenticator. You can configure your own instance of the Authenticator class or use one of the several built-in Authenticators:

Endpoints can configure an Access Control List (ACL) to govern which users can perform each HTTP operation.

HelloService.js
HelloEndpoint.js
        const carbon = require('carbon-io')
const __     = carbon.fibers.__(module)
const o      = carbon.atom.o(module).main
const _o     = carbon.bond._o(module)

__(function() {
  module.exports = o({
    _type: carbon.carbond.Service,
    port: 8888,
    authenticator: o({
      _type: carbon.carbond.security.MongoDBApiKeyAuthenticator,
      apiKeyParameterName: 'api_key',
      apiKeyLocation: 'header', // can be 'header' or 'query'
      userCollection: 'users',  // MongoDB collection where user objects are stored
      apiKeyField: 'apiKey'     // field that contains user api keys
    }),
    dbUri: 'mongodb://localhost:27017/mydb',
    endpoints : {
      hello: _o('./HelloEndpoint')
    }
  })
})
      
        const carbon = require('carbon-io')
const __     = carbon.fibers.__(module)
const o      = carbon.atom.o(module).main

module.exports = o({
  _type: carbon.carbond.Endpoint,
    acl: o({
    _type: carbon.carbond.security.EndpointAcl,
    groupDefinitions: { // This ACL defines a group called 'role'.
      role: 'role'      // We define a group called 'role' based on the user property named 'role'.
    },
    entries: [
      {
        user: { role: 'Writer' },
        permissions: {
          get: true,
          post: true
        }
      },
      {
        user: { role: 'Reader' },
        permissions: {
          get: true,
          post: false
        }
      }
    ]
  }),
  get: function(req) {
    return { msg: 'Hello World!' }
  },
  post: function(req) {
    return { msg: `Hello ${req.body.message}!` }
  }
})

      

Testing

View example on GitHub

Carbon.io comes with a testing library that makes it easy to manage large test suites. Here's an example of a HTTP-based test.

        const carbon = require('carbon-io')
const __     = carbon.fibers.__(module)
const o      = carbon.atom.o(module).main

__(function() {
  module.exports = o({
    _type: testtube.HttpTest,
    name: 'HttpTests',
    description: 'Http tests',
    baseUrl: 'http://localhost:8888',
    tests: [
      {
        reqSpec: {
          url: '/hello',
          method: 'GET'
        },
        resSpec: {
          statusCode: 200,
          body: 'Hello world!'
        }
      },
    ]
  })
})
      

Documentation Generation

Check out our official tutorial

Every Carbon.io Service is capable of generating its own docs. You can currently choose between Github-flavored Markdown or static HTML using Aglio. The docs here are auto generated from our official tutorial.