Package Exports
- studio
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (studio) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Studio.js
Micro-services using actors model framework for JavaScript.
Studio is a lightweight framework for node (it also runs on major browsers, but the priority is node projects) developed to make easy to create reactive applications according to reactive manifesto principles. It uses an actor model (freely inspired by akka actors) implemented using baconjs for reactive programming and bluebird a+ promises to solve the callback hell problem.
The main goal is to make all systems response, fault tolerant, scalable and mantainable. The development with Studio is (and always will be) as easy as possible, i'll keep a concise api, so other developers can create (and share) plugins for the framework.
Studio isn't only a library, it's a framework. It's really important to learn how to program and not only what each method can do.
I would love to receive feedback.Let me know if you've used it. What worked and what is wrong. Contribute and spread the word.
Table of contents
Install
To install execute:
npm install studioIntro
We all want our systems to be responsive, scalable, fault tolerant, mantainable and for the last, but not least, easy and fun to develop. With this goals in mind i decided to build a micro-services framework for nodejs using and architecture freely inspired on actor model. I present you Studio
Studio encourages you to use the best pratices of nodejs, it helps you to write simple, clean and completely decoupled code. And makes it very easy and fun.
First of all, almost everything in a Studio-based application is an Actor.
So if you're used to build SOA or micro-services all your services (and possible layers, as DAOs for instance) are going to be declared as a STATELESS SINGLETON actor. Actors have an unique identifier and communicate (always) asynchronously through message passing. The benefits of this approach is that it is really easy to take just some of your actors to different servers and make a better use of it. Also, your actors have the free benefit of being naturally indempotent (each actor receives a COPY of the message, so one actor can't mess with the objects of another actor) increasing your code security, use baconjs streams (which let you filter,map,buffer and do lots of different transformations to your messages) so you can keep your business rules apart for the validations increasing your code readability, and bluebird A+ promises to help you with the callback hell.
The other important class on Studio is the Driver.
A driver takes your endpoint input and parses it in a message for a certain actor.
And this is it... this is all you need to create reactive applications.
API
The API documentation can be accessed on Docs
Examples
Follow the link to see all available examples
Studio works with any web framework anf i'll create at least a "Hello World" application for the most used.
Here i`m going to put just a basic hello world with express, on examples folder you can see the best pratices and more pratical examples ( with promises, errors, filters...) Hello World with Express (using express 4.11.1):
var express = require('express');
var Studio = require('studio'); //require Studio namespace
var app = express(); // create an express app
//The first thing we have to do is create a driver to listen to the request
var driver = new Studio.Driver({
/*
Driver and Actor can receive an initialize function on constructor,
this function is going to be executed on object creation
*/
initialize: function () {
//Make express listen to '/' route
app.get('/', function (request, response) {
/*
we call the 'send' method of the driver passing express arguments,
Studio calls the 'parser' function of this driver to build a message and then deliver
this message to an actor, the send method ALWAYS returns a promise, so we call the
'then' method of this promise to take the actors response
*/
driver.send(request, response).then(function (helloMessage) {
response.send(helloMessage);
});
});
},
/*
All drivers needs a parser function which takes any object and transforms
into an object with the fields 'sender', 'receiver', 'body', 'headers'
*/
parser: function (request, response) {
//Since we don't need any request info we just fill the receiver's id
return {
sender: null,
receiver: 'helloActor', // receiver identifier
body: null,
headers: null
};
}
});
//Create an actor
var hello = new Studio.Actor({
id: 'helloActor', // All Actors needs an identifier
/*
All actors also needs a process function, this function is going to be executed
when a message arrives this function can return any object or a promise,
returning a object is going to automatically fulfill the sender promise.
You can also throw an exception if any error occurs,
and then the sender promise is going to be rejected
*/
process: function (body, headers, sender, receiver) {
/*An actor can communicate to others using the 'send' method as
this.send('otherActor',{foo:'bar'});
The 'send' message of an actor also returns a promise, so you can return it or use
then/catch to deal with the message
*/
return 'Hello World!!!';
}
});
app.listen(3000);// Listen on port 3000On examples folder you can learn how to deal with errors, how to buffer or filter messages and much more.
Pro tips
- The most important tip is LEARN HOW TO DEAL WITH A+ PROMISES, i think this blog have a incredible explanation of what A+ promises means and it saves you from callback hell
- Studio uses Baconjs streams to deliver messages, so use it, to filter , map and apply different transformations to your messages. Baconjs is a powerful tool to keep your code clean, you use it to keep your validations and non-functional requisites away from your actor process function. This way your actor will be more easy to read, mantainable and testable.
- All your actor must be indempotent , Studio helps you to achieve this delivering to each actor a copy of the original message. Stop keep states on your code.
- When dealing with stream transformation of an actor keep in mind you're dealing with (a copy of) raw message, the ray message have sender, receiver,body,headers and callback attributes, if you decide to filter a message you need to call the callback function manually to give to the blocked sender a response, the same applies for buffer.
Dependencies
Studio depends on:
- baconjs for stream manipulation
- bluebird for a+ promises usage
- csextends to make coffee classes extensible via javascript
Build
To build the project you have to run:
gruntThis is going to generate js files (and source-maps) on "compiled" folder and a browserified version of Studio on "dist" folder
Test
Run test with:
npm testLicense
The MIT License (MIT)
Copyright (c) 2015 Erich Oliveira ericholiveira.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
