X
X

Login

Login if you already have an account

LOGIN

Register

Create a new account. join us!

REGISTER

Support

Need some help? Check out our forum.

FORUM
Welcome to our Blog

The Post

FYI – FatFractal provides an amazingly flexible event model for your business logic (when foo changes, do bar)


As a developer, I want to be able to create business logic for my backend using a language that I am familiar with so that I can quickly implement my solution without having to learn something new.

I must confess that this is one of my favorite things about the FatFractal platform. Essentially this involves an amazingly simple method for creating business logic on your backend and I hope that you will find the freedom and flexibility as convenient and useful as I do.

Business Logic

I am used to creating object classes on my backend, and then writing lots of inline business logic to manage my objects (data). I would create actions like createOrder within which I would do all kinds of things like validation, notification, etc. within each one. All fine, but requires lots and lots of code, a lot of discipline to ensure consistency as well as to avoid overloading any particular function with too much cruft.

So now, Backend as a Service provides good CRUD methods making it easy to persist your data to the backend, but most leave a * huge * amount to be desired in terms of implementing business logic on the backend, relegating the developer to dealing with in the client code causing bloat, poor performance and data reliability concerns.

Maybe there is a better way…

As Gary writes in his blog about the origins of NoServer -

“The cloud should:

  • Store and retrieve my objects.
  • Securely – permissions and security should be robust and at a fundamental level.
  • Efficiently – with easy to create queries that get me what I want.
  • Execute code on the backend when my data changes (events).
  • Not prevent me from doing anything else that I want to do.”

Event Handlers/ User Stories

With FatFractal’s Event model, I am now free to define discrete pieces of functionality that are bound to events generated as my data “changes”. All together, they define my business logic for my application backend much easier than ever before.

This means that I need to think about things differently in terms of how I architect my code. The good news is that, if you are a fan of user stories as I am, then this you will find it interesting that this maps really well for those that can be implemented on the backend. You can literally implement one-for-one against user stories. It also means that I can implement my business logic with amazingly little code – very cool!

For example:

As the administrator of foo, I want to make sure that all requisite info is present before I store an Order so that I do not have a lot of zombie orders in my data.

exports.validateOrder = function() {
var order = ff.getEventHandlerData();
if (!order.amount || (order.amount <= 0) {
throw {statusCode:400, statusMessage:'An order amount greater than zero is required'};
}
}

As a vendor, I want to be alerted via email when an Order greater than $5000 is received so that I can be glad that I started this business afterall.

exports.alertBigOrder = function() {
var order = ff.getEventHandlerData();
if (order.amount >= 5000) {
var user = ff.getObjFromUri("ff/resources/FFUser/" + order.createdBy);
var name = user.firstName + " " + user.lastName;
var msgSubject = "Woo Hoo - you got an order for " + order.amount;
var msgString = "Order " + order.amount + " was created by " + name;
        ff.sendEmail ({
            host: "<mailserver>", port: "<port>",
            auth: "<true|false>", authPort: "<port>",
            username: "<username>", password: "<password>",
            from: "<fromAddress>", to: "<toAddress>",
cc: null, bcc: null, // included for completeness
            subject: msgSubject,
            text: msgString,
html: null // included for completeness. When supplied, the HTML message is
// sent, the text is also included as fallback if HTML viewing
// is not enabled in the receiver's email client
        });
}
}

Controlling your Event Handlers with FFDL

You have complete control over how these events are handled (SYNC (PRE or POST), ASYNC) as well as the order in which things are executed using FFDL (what’s this?). So to define the two functions above in your FFDL, you just add the following:

CREATE HANDLER validateOrder PRE ON /Order CREATE AS javascript:require (‘scripts/MyEventHandlers.js’).validateOrder();
This means that the validateOrder() function will be called when a new order is Created, but before the Order is actually stored (PRE). This ensures that the order has all the requisite info and prevents storing zombie orders.
CREATE HANDLER alertBigOrder ASYNC ON /Order CREATE AS javascript:require(‘scripts/MyEventHandlers.js’).alertBigOrder();
This means that when a new order is Created, an alert will be sent via email Asynchronously, but only after the PRE event is cleared.

So – there you have it! Events makes it really simple to visualize and implement your business logic with simple functions that are easy to create and maintain. While this makes it really easy to do many, many things – there are some things that need even more, and that is where Server Extensions come to bear. Will post about those soon.

Happy coding!

Kevin

For more information about Event Handlers, see here.

For more information about FFDL, see here.

See Gary’s blog post about the origins of NoServer here.

PaaS? BaaS? What?

Lots of people ask about the origins of NoServer, which is what we call FatFractal’s BaaS module.

We were in the process of building out our cloud fabric and one night, while building yet another demo app, I decided that all developer-centric cloud platforms really also ought to offer a way for developers to get 90% of what they need for the server-side of their app, out-of-the-box, while also trying to ensure that we not fence them in – i.e. give lots of functionality with minimum effort whilst also giving flexibility and extensibility to go beyond the box as you reach the edges of what is initially provided.

The 90% boiled down to the following. The cloud should:

  • Store and retrieve my objects.
  • Securely – permissions and security should be robust and at a fundamental level.
  • Efficiently – with easy to create queries that get me what I want.
  • Execute code on the backend when my data changes (events).
  • Not prevent me from doing anything else that I want to do.



The last point is really important! Whilst getting the other things makes my life a lot easier and will make me very happy for a month or two, if the flip side is that I then get stuck and as a result get frustrated and miserable, then I wouldn’t want it. So by June 2012 we had built enough to trial with customers – who loved it! – we launched our public beta in September, worked through the kinks in Oct-Dec :-) and we are now really focussed on getting the word out.

Meanwhile, some new marketing terms were emerging from other similar, but essentially different approaches. Platform as a Service (PaaS) and Backend as a Service (BaaS) are now terms that are used widely.

Upon reflection, it seems to me that they are both missing the point. PaaS is still very focused on a historical view of a set of IT problems, i.e. “stacks”. BaaS is seeking to provide more of a turnkey solution for application developers that treats the backend as a black box and is extremely limiting, invasive and prescriptive (smells like attempts at lock-in to me).

IMHO – what the market needs is a bit of both: a very smart cloud fabric that deals with infrastructure, monitoring, scalability, reliability, resilience etc, and also provides the ease of creation and out-of-the-box features that BaaS does, but does not limit the developer as a result. If I want to deploy some Java Code, Ruby Code or anything else in order to do something that I want to do, right alongside my “BaaS” stuff, then I should be able to.

So – in a nutshell, what we have so far built into NoServer is:

  • True fully qualified REST URIs
  • CRUD persistence
  • SDKs that operate at the data level and do not encroach into your code unnecessarily.
  • Amazingly straightforward modelling of your object graph’s relationships
  • Natural language, chained queries nested as deep as you want.
  • Strong authentication. SSL of course. Declarative access controls for your data which is sufficient for almost all use cases while also providing programmatic control (directly setting ACLs on objects) for when the declarative approach isn’t enough (which, so far, has been incredibly rare)
  • Exposed CRUD events with defined Event Handlers that execute your custom JavaScript code when they occur with synchronous (PRE or POST) as well as asynchronous modes. Currently we use RingoJS which allows you to do pretty much anything you need to do, including make HTTP requests; we also supply an API for sending Apple/Android push notifications, sending emails, image processing, and of course full access to your app’s datastore.
  • Server Extensions that allow you to extend your API with whatever server-side processing you want, and the ability to schedule scripts to run whenever you like



We’re pretty flexible at the server-side already, and I think you’ll agree we’re already better than (or *at least* as good as!) our BaaS competitors, but there’s lots more to come. Here’s a list of some of what’s coming over the next six months or so!

  • Greatly enhanced and pluggable authentication framework so that you can script integration with pretty much whatever 3rd-party identity / authentication cloud you like
  • Event Handlers for GET requests, and ‘virtual’ collections
  • Allowing mix and match of the powerful declarative access controls we already have with your own javascript for the really really edge cases (like, only allow access to this object if the current user lives in Idaho)
  • Enabling integration between NoServer and Rails backends. This is a big step towards completing our vision – i.e. if you reach the limits of what NoServer provides, then you should be able to extend your backend with some Ruby-on-Rails, or Java servlets, or NodeJS, or whatever
  • Allowing use of NodeJS modules in your NoServer server-side scripting

  • Full support for NodeJS applications on the FatFractal PaaS, and integration between NoServer / Node / Rails / Servlets modules in your app’s backend
  • And last, but definitely not least – and probably the most personally exciting to me given where I have spent a lot of my working life (i.e. large enterprise IT) – we will be working on evolving our products so that they can be leveraged by enterprises. More on that when the time comes :-)



I hope that you like what we have built – would very much appreciate your feedback.

Cheers,

Gary

In case you’re curious – NoServer is a tribute to the no-stuff (chamber, room, globe, ship) in Frank Herbert’s most excellent Dune series.

FYI – With FatFractal you can send text or html emails programmatically using our JS Server-side SDK.

As a developer, I want to be able to easily send emails from my backend so that I can validate users, create email reports and alert others to important information


There are many use cases where sending an email from your application backend. One is to notify someone when some data has changed. Another is for the purposes of validating a user. This post will cover how to do both with your FatFractal backend.

Text-only emails

The sendSMTPEmail method (docs) will send text-only email messages from an account that you specify. For example, if you want to send a notification email to alert you when a new object is stored – say an Order, is received by your app.

First, define an EventHandler (what’s this?) as follows that will extract info from the new Order object, get some additional information from your backend and the create a notification email to whomever you want to alert them that a new order was created. This should go in a file in the ff-scripts directory that was created when your app was created (more about this), in this case we will call it EventHandlers.js.

function notifyNewOrder() {
var order = ff.getEventHandlerData();
var user = ff.getObjFromUri("ff/resources/FFUser/" + order.createdBy);
var name = user.firstName + " " + user.lastName;
var msgSubject = "New Order notification";
var msgString = "Order " + order.amount + " was created by " + name;
ff.sendSMTPEmail("<mailserver>", "465", "true", "465", “<username>”, “<password>”, “<fromAddress>”, “<toAddress>”, msgSubject, msgString);
}

In your FFDL (what’s this?), you then define your EventHander like this:

CREATE HANDLER notifyNewOrder ASYNC ON /Order CREATE AS javascript:require (‘scripts/EventHandlers.js’).notifyNewApp();

HTML emails

The sendEmail method (docs) accepts a set of parameters and will send your html content via an email account that you specify. For this example, we will use a slightly more complicated example – we will send out

function sendWelcomeEmail() {
var user = ff.getEventHandlerData();
var subject = “Welcome to Foo - we are so glad you joined us”;
var html = getHtmlWelcomeMessage(user);
try {
var emailData = {
host:"<mailserver>",
port:"<port>",
auth:<true/false>,
authPort:"<port>",
username:"<username>",
password:"<password>",
from:"<fromAddress>",
to:user.email,
subject:subject,
text:text, html:html
};
emailData = JSON.parse(JSON.stringify(emailData));
ff.sendEmail(emailData);
} catch (error) {
throw "Caught exception: " + error + " while sending email";
}
}

And, include the FFDL for this EventHandler as well.

CREATE HANDLER validateUser POST ON /FFUser CREATE AS javascript:require (‘scripts/EventHandlers.js’).sendWelcomeEmail();

The above makes use of a function called getHtmlWelcomeMessage which fetches a template HTML file that I have included in the webapp directory of my app, replaces marked elements with personalized content and returns the HTML content using the http client that is available to your server side js code.

function getHtmlWelcomeMessage (user) {
var hc = require('ringo/httpclient');
var htmlMessage = hc.get(ff.getHttpAppAddress() + '/welcome_email.html').content;
htmlMessage = htmlMessage.replace("___FIRST_NAME___", user.firstName);
htmlMessage = htmlMessage.replace("___LAST_NAME___", user.lastName);
return '' + htmlMessage;
}

That’s it – super easy to send email content to your users or for internal notifications/ reports or whatever you want!

Happy coding!

Kevin

For more details about FFDL, the documentation is here.

For more details about the Server-side JS SDK, the documentation is here.

For more about EventHandlers, the documentation is
Event Handers Reference

FYI – FatFractal can host your web content as well as your data API

As the developer of mobile and web browser based apps, I want a backend that supports both web content as well as my data API

Mobile is hot and we love it! There are, however many times that you need web content as well as a data API for your apps.

With FatFractal, you have the choice of hosting web content somewhere else and using Cross Origin Resource Sharing (CORS) to allow those pages to access your data API in a browser – or – you can add your web content to your application structure delivered via the FatFractal cloud fabric together with your data.

So – here are the options for your webpage content…

Option 1 – Cross Origin Resource Sharing (CORS) between two hosts:

To enable CORS, all you need to do is edit the SET CORS in your application’s FFDL file to authorize another domain to access your backend in browser.

SET CORS https://anotherdomain.com

This will allow your web page to be hosted somewhere else to be access your data API from the FatFractal cloud.

Option 2 – Add your web content to your application footprint on the FatFractal cloud

When your application is scaffolded, we automatically create a webapp directory and you are free to add web content, subdirectories, css files, html files, js files, images, etc.
These will be served up as follows:

https://your_domain.fatfractal.com/your_application/your_content

DNS Settings

If your DNS provider supports domain forwarding/ masking, then you can configure your domain to “redirect” to the fatfractal url as above, but displays your domain in the browser. All that you need to do is set the forwarding url to:

https://your_domain.fatfractal.com/your_application/your_content

Then, if you enable masking, your domain will always appear in the browser location bar.

Alternatively, FatFractal can also take care of this for you. This involves setting an A Record on your DNS (a host) with the IP address of 50.17.255.197 which will be the host for your web content.

Then, to let Fatfrctal know that you want to map requests from this URL to your web content, add this line to your context.xml file in the ff-config directory that is in your scaffolded application.

<context domain=”your_domain” name=”your_application” default=”true”
map=”theurlyouwant.com”>
More information on Cross Origin Resource Sharing is here.

More information on FatFractal URI structures is here.

More information on the FatFractal Description Language (FFDL) is here.

Kevin

FYI – it is easy to integrate your backend with other web services

As a Developer, I want to integrate with other web services so that I can offload the integration tasks from my client to my backend.

Many times, you may want to utilize some other web service for the purposes of backend integration. FatFractal makes this really easy.

Let’s say you want to interact with SalesForce data from your backend…

FatFractal support the Common.js standard which includes an http client that let’s you do just about anything you want.

Example:

Here is some code that interfaces to to securely retrieve some information from a SalesForce API:

var hc = require('ringo/httpclient');

exports.getQs = function() {
var loginUrl = "https://login.salesforce.com/services/oauth2/token";
var apiVersion = "v25.0";
var username = "someUsername";
var password = "somePassword";
var securityToken = "someSecurityToken";
var clientId = "someClientId";
var clientSecret = "someClientSecret";

function LoginSF(username, password, securityToken, clientId, clientSecret) {
var data = {
grant_type: "password",
client_id: clientId,
client_secret: clientSecret,
username: username,
password: password + securityToken
};
var response = JSON.parse(hc.post(loginUrl, data).content);
return response;
}

function QuerySF(instanceUrl, accessToken, queryString) {
var url = instanceUrl + "/services/data" + apiVersion + "/query";
var data = {q: queryString};

var request = {
url: url,
data: data,
method: "GET",
headers: {
Authorization: "Bearer " + accessToken
}
};

var response = JSON.parse(hc.request(request).content);
return response;
}
// perform query
var loginResponse = LoginSF(username, password, securityToken, clientId, clientSecret, true);
var instanceUrl = loginResponse.instance_url;
var accessToken = loginResponse.access_token;
var queryResponse = QuerySF(instanceUrl, accessToken, "SELECT A__c, B__c, C__c FROM D__c");

var records = queryResponse.records;
for (var i = 0; i < records.length; i++) {
// DO SOME STUFF
// E.G. RETURN SOME DATA (SERVER EXTENSION)
// OR TAKE SOME ACTION (EVENT HANDLER)
}
}

What this does is define a function that can be used with an Event Handler or as an API extension with a Server Extension that logs in to an API on SalesForce.com, retrieves an instance_url and access_token that are need to then to execute a query and retrieve a response.

Many other things can be done with this powerful client – have fun!

Kevin

FYI – FatFractal supports many many to many many relationships (huh?)!


As a developer, I want to easily add many to many relationships between my objects without join tables so that I get a rich data model without getting data-model nightmares

With FatFractal, you can create amazing relationships between your objects. One of the things that makes this particularly useful is the ability to add multiple kinds of relationships from any particular object:

Example: If in your application.ffdl file that was created when you scaffolded your app, you include the following

CREATE OBJECTTYPE Comment (profile REFERENCE /Profile, comment STRING, relatedTo REFERENCE)
CREATE COLLECTION /Comment OBJECTTYPE Comment

This provides a ubiquitous “Comment” object that has two references and a “Comment” Collection typed to contain only “Comment” objects.

First, you will see a reference to the author public profile:

profile REFERENCE /Profile

This defines a relationship for the profile member which is bound to the /Profile Collection (which happens to contain only Profile objects thus “typing” the reference).

It also includes a reference called relatedTo:

relatedTo REFERENCE

This relationship is unique in that there is no Collection specifed, and thus no Objecttype implied. This means that the relationship for the relatedTo member can be to any object in any Collection of any Objecttype – i.e. is not “typed” and not bound to any particular Collection.

So now I have a comment object that has a reference to any other object in any other collection – pretty nice! All comments can are accessible via a single collection (/Comment) which is also nice.

But – what makes this truly useful is that you can also access comments via BackReferences to an object. For example, to see all comments (of Objecttype Comment) that relates to any particular object at all (as example, supR – a SupportRequest instance):

ff.getArrayFromUri(supR.ffUrl + "/BackReferences.Comment",
function(anArrayOfComments) {
// This returns an array of "Comments" that relateTo supR!!
},
function(onError) {}
}

Where the SupportRequest object model is defined as:

function SupportRequest() {
this.clazz = "SupportRequest";
this.subject = null;
this.body = null;
this.relatedTo = null;
this.profile = null;
return this;
}

Note that the SupportRequest does not even include anything about “Comment” in its definition. This means that you add relationships easily and intuitively without the pain of onerous data models – in short without the nightmares.

Hope this spurs some ideas for your application…

For more on the background of this, see Gary’s blog here.

For more details about FFDL, see the documentation here.

For more details about Queries, see the documentation here.

For more details about References and BackReferences, see the documentation here.

Kevin

FYI – it is easy to integrate your backend with other web services (for example, SalesForce.com)

As a Developer, I want to integrate with other web services so that I can offload the integration point from my client code to my backend for better performance, security and reliablility.

Many times, you may want to utilize some other web service for the purposes of backend integration. FatFractal makes this really easy. FatFractal supports the Common.js standard which includes an http client that let’s you do just about anything you want.

Let’s say you want to interact with SalesForce data from your backend…

Example:

Here is some code that securely retrieves some information from a SalesForce API that could be used in either a Server Extension of Event Handler:

var hc = require('ringo/httpclient');

exports.getQs = function() {
var loginUrl = "https://login.salesforce.com/services/oauth2/token";
var apiVersion = "v25.0";
var username = "someUsername";
var password = "somePassword";
var securityToken = "someSecurityToken";
var clientId = "someClientId";
var clientSecret = "someClientSecret";

function LoginSF(username, password, securityToken, clientId, clientSecret) {
var data = {
grant_type: "password",
client_id: clientId,
client_secret: clientSecret,
username: username,
password: password + securityToken
};
var response = JSON.parse(hc.post(loginUrl, data).content);
return response;
}

function QuerySF(instanceUrl, accessToken, queryString) {
var url = instanceUrl + "/services/data" + apiVersion + "/query";
var data = {q: queryString};

var request = {
url: url,
data: data,
method: "GET",
headers: {
Authorization: "Bearer " + accessToken
}
};

var response = JSON.parse(hc.request(request).content);
return response;
}
// perform query
var loginResponse = LoginSF(username, password, securityToken, clientId, clientSecret, true);
var instanceUrl = loginResponse.instance_url;
var accessToken = loginResponse.access_token;
var queryResponse = QuerySF(instanceUrl, accessToken, "SELECT A__c, B__c, C__c FROM D__c");

var records = queryResponse.records;
for (var i = 0; i < records.length; i++) {
// DO SOME STUFF
// E.G. RETURN SOME DATA (SERVER EXTENSION)
// OR TAKE SOME ACTION (EVENT HANDLER)
}
}

Note the inclusion of the httpclient at the top of the source:

var hc = require('ringo/httpclient');

The rest defines a function – “getQs” that can be used with an Event Handler or as an Server Extension that logs in to an API on SalesForce.com, retrieves an instance_url and access_token that are required to then to execute a query and retrieve a response.

Many other things can be done with this powerful client – have fun!

For more information on our Server-Side Javascript SDK, see here.

For more information on Event Handlers on your backend, see here.

For more information on Server Extensions on your backend, see here.

Kevin

FYI – Permissions can be inherited from other objects (pretty slick!)

As a Developer, I want to be able to implement access control policies that are inherited from another object so that I can easily propagate access control policies within my application.

If you want to set a default permission for objects in a collection that inherit permissions from another object, it is super easy using FFDL (what is FFDL?).

Example:

Say you have a Collection of JokeBook objects with permission defaults set and another Collection of Joke objects that have a reference to a JokeBook and you would like your Joke objects to inherit their default permissions from JokeBook objects. OK – short version is that I want the permissions for a Joke to be the same as the JokeBook they refer to.

The FFDL would look something like:

# JokeBook
CREATE OBJECTTYPE JokeBook (title STRING, writers REFERENCE /FFUserGroup, readers REFERENCE /FFUserGroup)
CREATE COLLECTION /JokeBooks OBJECTTYPE JokeBook
PERMIT read:object.readers write:object.writers ON /JokeBooks

This defines a JokeBooks Collection that contains Jokebook Objects that have a title, a reference to an author, a reference to a group of users with write access named writers and a group of users with read access named readers.

# Joke
CREATE OBJECTTYPE Joke (setup STRING, punchline STRING, book REFERENCE /JokeBook)
CREATE COLLECTION /Jokes OBJECTTYPE Joke
PERMIT read:object.book.readers write:object.book.writers ON /Jokes

This defines a Jokes Collection that contains Joke Objects which have a a reference called “book” from the JokeBooks Collection:

book REFERENCE /JokeBooks
So, you will notice that read and write permissions for a Joke object are set to refer to the read and write permissions (respectively) that are defined for the JokeBook object referred to by the “book” member.

PERMIT read:object.book.readers, write:object.book.writers ON /Jokes

Voila! Now the Joke object has the same permissions as the JokeBook object – as easy as that!

Of course, this is the default setting and you can always change the access to any particular object programmatically in your application code.

Hope you find this useful!!

For more details, see the FFDL documentation here.

To see the other things you can do with permissions see here.

Contact