distro

An small simple wrapper over UDP Datagrams to create clients/servers with an standard message format.

"Distro" encapsulates the work needed to servers and clients for distributed systems.

0.4.0 Removed Redis into distro-redis as a plug-in 0.3.1 Added documentation for 0.3.0 0.3.0 Added support for Redis and major changes on the API. 0.0.5 Added support for TCP servers and clients 0.0.2 Initial release

The API of version 0.3.1 has significant changes when compared to the previous versions, please read below.

The distro module is intended to simplify the way services communicate with each other. It abstracts several different transports while providing a consistent interface. It also specifies a message format and comes with some helper factories to create and parse those messages.

It comes with some pre-packaged trasports for udp4, udp6 and tcp. You can also use redis (using pub-sub) via the distro-redis module plug-in. You can easily create your own transports as plug-ins as well (more details below). Note that there is not inter-operability between transports. Both clients and servers have to use the same transport to be able to talk to each other.

Let's say you have an orders service that creates orders for customers. You also want to keep the rolling total for a given customer and you want the customer service to update the data on the customer.

Distro can easily dispatch a message to the proper service. On the orders service you will have some code like this:

var updateCustomer = distro.createMessage({uri: "/customer/", address: 'orders.services.com',  port: 442200}; {})
distro.create('tcp').client({port: 41234, address: 'customer.service.com'}).send(updateCustomer);

Simple do npm install distro

Creating a server is as simple as given the name of the transport to use and some server information needed for configuration.

var distro = require("distro");

var server = distro.create('udp4')
  .server({port: 41234});

Supported transports at the moment are 'udp4', 'udp6' and 'tcp'.

You can register multiple handlers per server.

server.receive(handler1);
server.receive(handler2)

Servers can register handles for different verbs or for all the verbs.

server.receive(handleAllRequests);
server.post(uri, handlePost);
var distro = require("distro");

var client = distro.create('udp4')
  .client({port: 41234});

The send method takes a distro Message that you can easily create using the library.

var msg = distro.message({uri: "/identifier/"}, "Payload can be anything, even a string");
client.send(msg);

If you want to use the distro-redis plugin just add the distro-redis module to your package.json and create a new server or client passing the module as the argument of the create method.

var distro = require("distro");
var distroRedis = require("distro-redis");

var client = distro.create(distroRedis)
  .client({port: 41234});

var server = distro.create(distroRedis)
  .server({port: 41234});

Messages need at least two parameteres, a headers object and a payload. The headers needs at least one property (uri).

var header = {uri: "/object/main" };
var msg = distro.message(headers, payload);

If you want to receive confirmation once the message is received you can add the information for the server that will receive the confirmation to the headers object. (This structure will change in the next version)

var header = {
  uri: "/object/main",
  address: "localhost",
  port: 42234
};
var msg = distro.message(headers, payload);

The server(s) that receives a message with origin information will send back a RECEIVED message to such origin. (This will change as well in the next version) The payload of a RECEIVED message is the id of the message.

Messages Id are autogenerated UUID, the payload of a message can be any JSON serializable object. This is a very important consideration since recursive objects will not work properly at the moment.

The headers object can have a verb property that maps to some of the http verbs. At the moment the supported verbs are HEAD, GET, POST, PUT, DELETE and PATCH.

What do I mean with supported verbs, you may ask?

The server object can register different handlers for each of those verbs. Instead of registering handlers with the receive method you can use specific verbs methods.

var server = distro.create('tcp')
  .server({port: 41234})

server.head(uri, handleHeadVerb);
server.get(uri, handleGetVerb);
server.post(uri, handlePostVerb);
server.put(uri, handlePutVerb);
server.del(uri, handleDeleteVerb);
server.patch(uri, handlePathVerb);

You don't need to specify the get verb for messages. If you registered handlers with the get method and your messages don't have a verb, this handler(s) will be used.

You can still add handlers to receive that will be called no matter the verb (or the uri) of the messages, this can be helpful for audit, logging or error handlers purposes.

Given a serialized Message returns a Message object

Creates a new Message object with the given headers and payload.

transport can be a string identifying the bundled transport or a transport object. The logger is any object that implements the log method. If a logger is not given the native console object will be used.

Returns a distro object

The serverInfo object contains the port and address for the underlying transport. If adrress is not provided the default is localhost or 127.0.0.1

Returns a Server object.

The serverInfo object contains the port and address for the underlying transport. If adrress is not provided the default is localhost or 127.0.0.1

Returns a Client object.

Adds a listener that will be called each time the server is called, without consideration of the verb or uri used in the message headers

Adds the listener to be called when a message is received for the given verb and uri specified on the message headers

Stops and close the server.

The message have to be a Message object.

The id is expected to be a UUID. The headers object contains a uri, an address for the server/client to talk to and a port number. The payload should be a 'flat' serializable object.

You will usually create new messages using the .message() method of the library directly.

Returns a string representation of a serialized Message

Return a buffer with the result of calling toString() on the Message