Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master

0.0.2 Release

- Moved error logging into separate radialError method.
- Exposed radialError and radialResponse
latest commit cc35aae0d0
Brian Knapp brianknapp authored
README.markdown

Introduction

radial-js is the javascript node.js implemention of the radial framework for the radial platform.

The goal of radial is to make it really fast to write testable, reliable services in the language of your choice.

Platform

radial is a node.js framework built on top of express, but as part of the radial platform a compatible framework will be available in other languages.

Using radial

To use radial you have to do two things:

var radial = new require('./lib/radial.js')

global.radial = radial

app.post('/api', function(req, res) { radial.handler(req, res) })

That is basically it.

radial will look in the /services folder of your app for index.js. In that object you will map out all your services.

All services should live in the /services folder of your app.

Request Object

A request is defined as a JSON object consisting of a method string and a params object.

{
   method: "service_name.method_name" , 
   params: {
              param1: "some info" ,
              param2: "more info" ,
              param3: "and so on"
           }
}

"service_name" is the name that the service object is registered as

"method_name" is the name of the method being called on that service.

For example you could have the FooService.js file mapped to "fooService" and it could have a method named blah, so the method string would in that case be "fooService.blah". You are free to use whatever naming scheme you desire in mapping your service objects.

All service object methods take a single parameter as input. By convention it will be called input, but you can call it whatever you want.

Response Object

A response object is defined as a JSON object consisting of a data object and an error object. If dada is set than error must be null and vice-versa.

{
   response: {
                success: "true"
             }
   error: null
}

The radial response class defines getters and setters for both error and data and has a custom toJSON object to allow for serialization of the private data and error variables.

RadialError Object

The error object is thrown inside service methods and it extends the standard Error object.

It looks something like this:

{
   prefix: "service_name method_name" , 
   code: "1" , 
   message: "Example message of how something went wrong"
   type: "could_be_anything"
   data: {
            sample_data: "foo"
         }
}

prefix - A shorthand representation of the service and the method where an error occurred. This is for debugging information and isn't always going to be te same as the service/method you requested.

code - The error code you assign to the error. These should be localized to the function you throw the error from. There is no concept of global error codes in radial.

message - A human readable error message that succintly explains the error as best as possible.

type - A secondary classification of error type that can be used by an application to react to specific kinds of errors without having to worry about error codes being changed.

data - An object that can be used to pass data back for errors that need to be acted on in a nonstandard way. For example, certain authentication errors might need to pass data through a response even though the service call was unsuccessful.

The RadialError object has a simple constuctor that you pass all of the error information into and a toJSON method that will seralize the error properly.

The Tester

The tester is a simple service testing tool that makes AJAX calls using jQuery to our radial services.

You specify the radial services method, and the params.

The tester makes the ajax call and displays the JSON response.

By default this is located at /test.html

Services Calling Services

Understanding how services call services is critical to properly using this framework. It is a particularly tricky concept in node because of the async nature of node and how callbacks are handled.

To accomidate the async pattern there are essentially two kinds of service functions - service endpoints and service callbacks.

Service endpoints are exposed publicly and follow this format:

function endpoint(params, res, callback) {
  doMagic();
  callback(null, data, res);
}

Service callbacks should be kept private if possible and follow this format:

function callback(error, data, res) {
  doSomething();
}

Callbacks inside service functions end up relying on closures to be able to make the final callback to the systemwide response. The code ends up looking like this.

var innerCallback = function(error, data, res) {
  doSomething();
  callback(error, data, res);
}

service.action(params, res, innerCallback);
return;

This pattern of a innerCallback function closure inside of a service function allows you to pass on the radial.callback method or whatever callback is sent to the original service. It adds somewhat to code complexity on the individual function level, but it allows any service function to call any other service function so that chaining and composite services are possible in a fully async manner.

In general, service enpoints will be responsible for logic and callbacks will likely just be used for data passing to keep things simple. This may lead to some complex service chaining and compositing, but it will keep the system testable and scalable.

Going forward these patterns are somewhat subject to change as the concepts behind radial grow and evolve.

Security Service

radial doesn't presume to know how you want to secure your system. However, it does make a few assumptions about some best practices.

https only - All communication with the services will happen via https. That way it is less likely that someone is going to intercept passwords or anything like that.

using heroku - The way radial enforces https is heroku-specific, so if you aren't on heroku, you need to tweak the code.

Security.check - radial assumes that you will have a security service with a check method that will check the permissions before allowing any service method to execute. The default Security.check method just returns true, so you need to modify that to suit your needs.

Something went wrong with that request. Please try again.