Telerik blogs

An easy-to-use Back-end-as-a-service (BaaS) can make rapidly developing your app not only a possibility, but an enjoyable experience. A good BaaS will work for simple "CRUD-based" (or "forms-over-data") apps as well as more complicated scenarios. The trouble is that when your app outgrows the simpler scenarios, you often need "hooks" on the server side for things like validation, record transformation and more. When you're using Everlive, this is where "Cloud Code" comes in.

What is Cloud Code?

"Cloud Code" enables you to execute JavaScript before or after "CRUD" (Create-Read-Update-Delete) operations in Everlive. So that means the following events have hooks to where you can execute "Cloud Code":

  • Before Create
  • After Create
  • Before Read
  • After Read
  • Before Update
  • After Update
  • Before Delete
  • After Delete

(Sensing a pattern here? :-))

As you'd expect, any of the Before events are executed before the request is processed. Conversely, any After events are executed after the request has been processed.

These CRUD hooks are available on any Content Type you create (as well as the built-in Users Content Type).

How do You Use It?

While you can upload JavaScript files to Everlive, most of the time (at least initially), you will be using Everlive's web interface to add cloud code. To use the web interface, simply follow these steps:

  • Log into Everlive
  • Pick the Project
  • Click on the "Types" link (on the left)
  • Select the Content Type for which you want to create Cloud Code
  • Click the "Cloud Code" link near the top right

You'll then see a code editor open, pre-populated with the Everlive Cloud Code event hooks:

Editing Cloud Code

If this is the first time you've edited Cloud Code for this Content Type, you'll see the following JavaScript stubbed out for you:

Everlive.Events.beforeRead(function(request, context, done) {
    //Enter your custom code here

    //Call done() once you are finished
    done();
});

Everlive.Events.afterRead(function(request, response, context, done) {

    done();
});

Everlive.Events.beforeCreate(function(request, context, done) {

    done();
});

Everlive.Events.afterCreate(function(request, response, context, done) {

    done();
});

Everlive.Events.beforeUpdate(function(request, context, done) {

    done();
});

Everlive.Events.afterUpdate(function(request, response, context, done) {

    done();
});

Everlive.Events.beforeDelete(function(request, context, done) {

    done();
});

Everlive.Events.afterDelete(function(request, response, context, done) {

    done();
});

Looking at the above code, we can see that:

  • Each "before/after" hook is a method that takes a callback containing the logic you want executed.
  • The callback signature for "before" events has three arguments: request, context and done.
  • The callback signature for "after" events has four arguments: request, response, context and done.
  • The done argument to the callbacks is itself a callback that you should invoke when your logic is complete. This is how you tell Everlive that it can move on and finish processing the request (not invoking it will result in your request timing out!).

What About Those Other Arguments?

For both types of events, the request argument contains data about the current request, and the context argument is used to pass data from a "before" event (ex. - beforeRead) to the corresponding "after" event (ex - afterRead). The response argument in an "after" event is exactly that - the response Everlive is returning to the client.

Enough talk - let's see this in action.

Adding Behavior to an Event

Bordering on the "contrived" side of examples (let's roll with it, though), let's pretend we have a content type that includes a field to store a country code, and we want to ensure that it's always upper-case (of course, we could do this on the client instead/as well). It's as simple as editing the beforeCreate hook as follows:

Everlive.Events.beforeCreate(function(request, context, done) {
    if(request.data.CountryCode) {
        request.data.CountryCode = request.data.CountryCode.toUpperCase();
    }
    done();
});

Easy, huh?

Canceling Requests

So - let's say it's a Monday for you and you're really tired of people not including a valid country code. You know it might be a bit harsh, but the power of Cloud Code is at your fingertips, so you decide to cancel requests that do not contain a country code:

Everlive.Events.beforeCreate(function(request, context, done) {
    if(!request.data.CountryCode) {
        Everlive.Request.cancel();
    }
    done();
});

Modifying the Response

After your badly needed Monday morning coffee, you realize that cancelling requests missing a country code was a bit severe. Instead, you decide to modify the response returned to the client by adding a message that your client-side framework can interpret in order to show a friendly notification to the user:

Everlive.Events.beforeCreate(function(request, context, done) {
    if(!request.data.CountryCode) {
        context.missingCountryCode = true;
    }
    done();
});

Everlive.Events.afterCreate(function(request, response, context, done) {
    if(context.missingCountryCode) {
        response.additionalData.message = "Show some national pride and include your country code sometime!";
    }
    done();
});

In the above example, we used the context argument of our beforeCreate event to pass information on to our afterCreate event (in this case, if they left of the country code we set missingCountryCode to true). For any users that leave off the country code, the response to their request will include a message property (in addition to the usual Result property) that contains the string message above.

Let's Get Real, Please

I know, right? The Country Code example was just to whet your appetite. You can do record transformation and validation inside Everlive's Cloud Code hooks if you like, but there are other use cases that you may run across first.

Customizing Responses

Filtering to Specific Fields

You can provide querying expressions in a beforeRead hook to customize how/what gets returned to the client. For example, this would only return the UserName and CountryCode fields (in addition to the ID, which is always returned):

Everlive.Events.beforeRead(function(request, context, done) {
    request.fieldsExpression = { UserName : 1, CountryCode : 1 };
    done();
});

Sorting Results

Maybe you'd like to sort the results by CountryCode before returning it to the client - no problem!

Everlive.Events.beforeRead(function(request, context, done) {
    request.sortExpression = { CountryCode : 1 };
    done();
});

Aside from sorting and limiting results to certain fields, several other query expressions are supported. See the docs for more info on querying.

Calling Other HTTP Services

It's very possible that you'll run into a situation where you need to call out to an external web service from within your Cloud Code. You can so this by using the Everlive.HTTP.request(method, url, options, callback) method in your code cloud:

Everlive.Events.beforeRead(function(request, context, callback) {
    Everlive.Http.request('GET',
        'http://some/external/api',
        {},
        function(error, response) {
            if(error){
                request.data.error = error;
            } else {
                request.data.otherInfo = response;
            }                
            done();
        });
});

Everlive.Http also provides convenience methods (get, post, delete, and put), so the above snippet could be changed to:

Everlive.Events.beforeRead(function(request, context, callback) {
    // signature is get(url, options, calback)
    Everlive.Http.get(
        'http://some/external/api',
        {},
        function(error, response) {
            if(error){
                request.data.error = error;
            } else {
                request.data.otherInfo = response;
            }                
            done();
        });
});

Just be careful, though - Cloud Code execution needs to happen in 5 seconds or less - otherwise a timeout will occur. Slow external services will definitely put you at risk here.

The Silver Lining Looks Good From Here

We've just covered a few examples of how Cloud Code can be useful to you. I highly recommend checking out our documentation for even more examples. It covers things like using Cloud Code to send emails & SMS messages, as well as sending custom data in HTTP Headers from your client that can be used in special logic in Cloud Code.

Everlive has a lot of flexibility and power available to you - and no doubt a feature like Cloud Code will come into play as your needs grow. The fact that there are Everlive SDKs for .NET, JavaScript, Windows Phone and iOS clients means that your needs can grow across multiple platforms, all easily sharing data and Cloud Code logic.

About the Author
Jim Cowart

About the Author

Jim Cowart

Jim Cowart is an architect, developer, open source author, and overall web/hybrid mobile development geek. He is an active speaker and writer, with a passion for elevating developer knowledge of patterns and helpful frameworks. 

Comments

Comments are disabled in preview mode.