<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>FatFractal.com</title>
	<atom:link href="http://fatfractal.com/prod/feed/" rel="self" type="application/rss+xml" />
	<link>http://fatfractal.com/prod</link>
	<description>From Code to Cloud</description>
	<lastBuildDate>Sun, 09 Jun 2013 07:37:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>FYI &#8211; FatFractal improves authentication support with full OAuth 1.0 and OAuth 2.0 support</title>
		<link>http://fatfractal.com/prod/fyi-fatfractal-improves-authentication-support-with-full-oauth-1-0-and-oauth-2-0-support/</link>
		<comments>http://fatfractal.com/prod/fyi-fatfractal-improves-authentication-support-with-full-oauth-1-0-and-oauth-2-0-support/#comments</comments>
		<pubDate>Tue, 04 Jun 2013 01:40:21 +0000</pubDate>
		<dc:creator>Kevin Nickels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[oauth1]]></category>
		<category><![CDATA[oauth2]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=10890</guid>
		<description><![CDATA[User authentication is an ages old problem for developers that has greatly improved recently thanks to the emergence of trusted providers such as Twitter and Facebook. FatFractal has provided integrated authentication with Facebook and Twitter on the client-side for some time. We have just released a major upgrade to our backend support for full OAuth 2.0 as well as OAuth ...]]></description>
			<content:encoded><![CDATA[<p><strong><br />
<em>User authentication is an ages old problem for developers that has greatly improved recently thanks to the emergence of trusted providers such as Twitter and Facebook. </em></strong></p>
<p>FatFractal has provided integrated authentication with Facebook and Twitter on the client-side for some time. We have just released a major upgrade to our backend support for full OAuth 2.0 as well as OAuth 1.0 using the Scribe library.</p>
<p>Implementing single-sign-on using a trusted provider like Facebook or Twitter makes a lot of sense. Now, implementing this has gotten a lot easier. The basic steps to using either as an authentication provider with FatFractal are:</p>
<ol>
<li>Register your application with the provider</li>
<li>Add the keys from one or both to the Auth.js file that is created during application scaffolding</li>
<li>Implement the auth life-cycle in your application</li>
</ol>
<p>Full documentation for the FatFractal ScriptAuth process is found <a title="http://fatfractal.com/docs/scriptable-authentication/" href="http://fatfractal.com/docs/scriptable-authentication/" target="_blank">here</a></p>
<p><a name="you-can-see-working-code-for-everything-below-here"></a><br />
<h5>You can see working code for everything below (<a title="https://fyi.fatfractal.com/scriptauth/index.html" href="https://fyi.fatfractal.com/scriptauth/index.html" target="_blank">here</a>).</h5>
<p>First, you need to add the application keys for Twitter and/ or Facebook into the Auth.js file that is automatically created for you when you scaffold your application with FatFractal. The Auth.js code looks like this:</p>
<pre class="brush: jscript; title: ; notranslate">
auth.setScribeApiClassName(TWITTER, &quot;org.scribe.builder.api.TwitterApi&quot;);
auth.setScribeApiKey(TWITTER, &quot;twitter_api_key&quot;);
auth.setScribeApiSecret(TWITTER, &quot;twitter_api_secret&quot;);

auth.setScribeApiClassName(FACEBOOK, &quot;org.scribe.builder.api.FacebookApi&quot;);
auth.setScribeApiKey(FACEBOOK, &quot;facebook_app_id&quot;);
auth.setScribeApiSecret(FACEBOOK, &quot;facebook_app_secret&quot;);
</pre>
<p>You need to replace the ApiKey and ApiSecret values with the corresponding values for Facebook and/ or Twitter. Then, the basic components needed for the sample app above are (in HTML/Javascript) are quite straightforward:</p>
<ol>
<li>Create a login for Facebook function</li>
<li>Create a login for Twitter function</li>
<li>Create a page that will handle process the callback from the provider and redirect back the application page with the user logged in</li>
</ol>
<p>Next, we set up the callback URI that both will use (you could also create separate pages fors handling Facebook or Twitter if you prefer).</p>
<pre class="brush: jscript; title: ; notranslate">
var callbackUri = ff.getBaseUrl() + &quot;authorize.html&quot;;
sessionStorage.setItem(&quot;ff-callback-uri&quot;, callbackUri);
ff.setCallbackUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, callbackUri);
ff.setCallbackUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER, callbackUri);
</pre>
<p>Note that we are saving the callback in sessionStorage as we will want to use that later from the authentication page.</p>
<p>Here is the code for launching the Facebook login process:</p>
<pre class="brush: jscript; title: ; notranslate">
// Facebook login
function facebookLogin() {
    ff.authUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK,
        function(authUri) {
        sessionStorage.setItem(&quot;ff-auth-provider&quot;, &quot;FACEBOOK&quot;);
        window.location = authUri;
    }, function(code, msg) {
         console.error(&quot;facebookLogin() Error: &quot; + code + &quot; &quot; + msg);
    });
}
</pre>
<p>And, here is the code for launching the Twitter login process:</p>
<pre class="brush: jscript; title: ; notranslate">
// Twitter login
function facebookLogin() {
    ff.authUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, function(authUri) {
        sessionStorage.setItem(&quot;ff-auth-provider&quot;, &quot;FACEBOOK&quot;);
        window.location = authUri;
    }, function(code, msg) {
         console.error(&quot;facebookLogin() Error: &quot; + code + &quot; &quot; + msg);
    });
}
</pre>
<p>Note that we are also saving the authentication provider in sessionStorage as well in order to have a single page to handle the response.</p>
<pre class="brush: jscript; title: ; notranslate">
var callbackUri = sessionStorage.getItem(&quot;ff-callback-uri&quot;);
var provider = sessionStorage.getItem(&quot;ff-auth-provider&quot;);
var ff = new FatFractal();
if(provider == &quot;FACEBOOK&quot;) {
   ff.setCallbackUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, callbackUri);
   ff.retrieveAccessTokenForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, location.href, function() {
      ff.loginWithScriptAuthService(ff.SCRIPT_AUTH_SERVICE_FACEBOOK, function(user) {
      var msg = &quot;Success! Logged in as &quot; + user.guid;
      var el = document.getElementById('status');
      el.innerHTML = &quot;&lt;br&gt;&lt;div class = 'well'&gt;Logged in with Facebook - message: &quot; + msg + &quot;&lt;/div&gt;&quot;;
      window.location = &quot;index.html&quot;;
      });
   });
} else if(provider == &quot;TWITTER&quot;) {
   var requestToken = JSON.parse(sessionStorage.getItem(&quot;ff-tw-request-token&quot;));
   sessionStorage.removeItem(&quot;ff-tw-request-token&quot;);
   ff.setCallbackUriForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER, callbackUri);
   ff.setRequestTokenForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER, requestToken);
   ff.retrieveAccessTokenForScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER,
      location.href, function() {
      ff.loginWithScriptAuthService(ff.SCRIPT_AUTH_SERVICE_TWITTER, function(user) {
         var msg = &quot;Success! Logged in as &quot; + user.guid;
         var el = document.getElementById('status');
         el.innerHTML = &quot;&lt;br&gt;&lt;div class = 'well'&gt;Logged in with Twitter -  message: &quot; + msg + &quot;&lt;/div&gt;&quot;;
         window.location = &quot;index.html&quot;;
      });
   });
} else console.error(&quot;Could not determine the OAuth provider&quot;);
</pre>
<p>When the callback is received, this page will complete the authentication process, create the logged in user and session and redirect back the original page logged in.</p>
<p>That&#8217;s it, </p>
<p>Kevin</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-fatfractal-improves-authentication-support-with-full-oauth-1-0-and-oauth-2-0-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FYI &#8211; Datagraph with Objects and Collections</title>
		<link>http://fatfractal.com/prod/fyi-datagraph-with-objects-and-collections/</link>
		<comments>http://fatfractal.com/prod/fyi-datagraph-with-objects-and-collections/#comments</comments>
		<pubDate>Mon, 20 May 2013 18:32:03 +0000</pubDate>
		<dc:creator>Kevin Nickels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[classes]]></category>
		<category><![CDATA[collections]]></category>
		<category><![CDATA[ffdl]]></category>
		<category><![CDATA[objecttypes]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=10833</guid>
		<description><![CDATA[As a developer, I want to have complete control of my objects and collections on the backend. There are so many terms being thrown around these days that it is often difficult to separate the truth from the marketing hype. So &#8211; at FatFractal, when we talk about our Datagraph capabilities, we mean a real graph, not marketing hype. To ...]]></description>
			<content:encoded><![CDATA[<p><strong><br />
<em>As a developer, I want to have complete control of my objects and collections on the backend.<br />
</em></strong></p>
<p>There are so many terms being thrown around these days that it is often difficult to separate the truth from the marketing hype. So &#8211; at FatFractal, when we talk about our Datagraph capabilities, we mean a real graph, not marketing hype. To illustrate, let me show you a couple of simple examples.<a name="you-can-see-working-code-for-everything-below-hereyou-can-access-the-source-code-for-the-sample-application-here"></a><br />
<h5>You can see working code for everything below (<a href="http://fyi.fatfractal.com/objectandcollections/" title="http://fyi.fatfractal.com/objectandcollections/" target="_blank">here</a>).<br />You can access the source code for the sample application (<a href="https://github.com/FatFractal/fyi.objectsandcollections" title="https://github.com/FatFractal/fyi.objectsandcollections" target="_blank">here</a>).</h5>
<p>Most of the time, you will define an object and map it to a identical collection.</p>
<p>Let’s start with couple of simple object definitions:
<pre class="brush: jscript; title: ; notranslate">
function Movie() {
    this.title = null;
    this.description = null;
    this.year = null;
}
</pre>
<pre class="brush: jscript; title: ; notranslate">
function Actor() {
    this.firstName = null;
    this.lastName = null;
}
</pre>
<p>Then, we add the following to our FFDL (<a href="http://fatfractal.com/docs/application-configuration/#fatfractal-definition-language-ffdl" title="FatFractal FFDL overview" target="_blank">what’s this</a>?), to define these object types and collections on the backend as follows:</p>
<pre class="brush: jscript; title: ; notranslate">
CREATE OBJECTTYPE Movie (title STRING, description STRING, year NUMERIC) 
CREATE OBJECTTYPE Actor (firstName STRING, lastName STRING)
CREATE COLLECTION /Movies OBJECTTYPE Movie
CREATE COLLECTION /Actors OBJECTTYPE Actor
</pre>
<p>Note &#8211; that the two collections are typed to an object type (Movie and Actor), which means that attempting to store a Movie in the Actors collection or vice-a-versa  will generate a validation error.</p>
<p>But, let’s say that you want to create a collection of favorites and allow it to hold different object types, while also still being able to distinguish them from each other. No problem, to do that, let’s add a new collection called Favs that is not typed:</p>
<pre class="brush: jscript; title: ; notranslate">
CREATE COLLECTION /Favs OBJECTTYPE *
</pre>
<p><a name="examples"></a><br />
<h3>Examples:</h3>
<p>First, let’s store an object in a collection typed to a Movie object type:</p>
<pre class="brush: jscript; title: ; notranslate">
var m = new Movie();
m.title = &quot;Argo&quot;;
m.description = &quot;Argo is a 2012 historical drama thriller film directed by Ben Affleck.&quot;;
m.year = 2012;
ff.createObjAtUri(m, &quot;/Movies&quot;);
</pre>
<p>Now &#8211; let’s try saving a Movie to the Favs collection&#8230;</p>
<pre class="brush: jscript; title: ; notranslate">
ff.createObjAtUri(m, &quot;/Favs&quot;);
</pre>
<p>Similarly, you can store an Actor in the Actors collection or in the Favs collection&#8230;</p>
<pre class="brush: jscript; title: ; notranslate">
var a = new Actor();
a.firstName = &quot;Ben&quot;;
a.lastName = &quot;Affleck&quot;
FatFractal.createObjAtUri(a, &quot;/Actors&quot;);
FatFractal.createObjAtUri(a, &quot;/Favs&quot;);
</pre>
<p>But, if you try to store a Movie in the Actors (or vice-a-versa) collection, you will get an error&#8230;</p>
<pre class="brush: jscript; title: ; notranslate">
FatFractal.createObjAtUri(m, &quot;/Actors&quot;);
</pre>
<p>Now &#8211; let’s see how you can retrieve objects of a particular class from a collection that holds more than one object type.</p>
<p>Get all the Movie objects from the Favs collection&#8230;</p>
<pre class="brush: jscript; title: ; notranslate">
ff.getArrayFromUri(&quot;/ff/resources/Favs/(clazz eq 'Movie')&quot;, function(r) {
    // handle success
}, function(code,message){
    // handle error
});
</pre>
<p>Get all the Actor objects from the Favs collection&#8230;</p>
<pre class="brush: jscript; title: ; notranslate">
ff.getArrayFromUri(&quot;/ff/resources/Favs/(clazz eq 'Actor')&quot;, function(r) {
    // handle success
}, function(code, message){
    // handle error
});
</pre>
<p>Get all the objects from the Favs collection&#8230;</p>
<pre class="brush: jscript; title: ; notranslate">
ff.getArrayFromUri(&quot;/ff/resources/Favs/&quot;, function(r) {
    // handle success
}, function(code, message){
    // handle error
});
</pre>
<p>That’s it &#8211; we hope that you will agree that this is another example of FatFractal being the most flexible, robust and capable backend for your app &#8211; enjoy!</p>
<p>Kevin</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-datagraph-with-objects-and-collections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FYI &#8211; Retrieve an object graph in a single query with FatFractal</title>
		<link>http://fatfractal.com/prod/fyi-retrieve-an-object-graph-in-a-single-query-with-fatfractal/</link>
		<comments>http://fatfractal.com/prod/fyi-retrieve-an-object-graph-in-a-single-query-with-fatfractal/#comments</comments>
		<pubDate>Sat, 16 Mar 2013 01:23:53 +0000</pubDate>
		<dc:creator>Kevin Nickels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[back references]]></category>
		<category><![CDATA[datagraph]]></category>
		<category><![CDATA[queries]]></category>
		<category><![CDATA[references]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=10563</guid>
		<description><![CDATA[As a developer, I want an easy to navigate data model (a datagraph) so that I can get the data I want with fewer API calls which increases my applications performance and saves me money. We have added a new capability that allows you to retrieve an object graph (the object as well as all of its REFERENCES and GRABBAGS) ...]]></description>
			<content:encoded><![CDATA[<p><strong><br />
<em>As a developer, I want an easy to navigate data model (a datagraph) so that I can get the data I want with fewer API calls which increases my applications performance and saves me money.<br />
</em></strong></p>
<p>We have added a new capability that allows you to retrieve an object graph (the object as well as all of its REFERENCES and GRABBAGS) in a single API call. This can improve the the performance of your application and reduce the &#8220;chattiness&#8221; of using your API.</p>
<p>Previously, you could retrieve an object from a URI such as:</p>
<p><a href="http://telluride.fatfractal.com/tff39/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4">http://telluride.fatfractal.com/tff39/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4</a></p>
<p>For which you would get a response like this&#8230;<br />
<h6 class="toggle"><a href="#">Click to see response</a></h6>
<div class="toggle_content" style="display: none;">
<div class="block">
<pre class="brush: jscript; title: ; notranslate">
{
    &quot;result&quot;:
        [
            {
                &quot;ffUserCanEdit&quot;: false,
                &quot;ffUrl&quot;: &quot;/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4&quot;,
                &quot;qa&quot;: false,
                &quot;ffRL&quot;: &quot;/Showings&quot;,
                &quot;updatedBy&quot;: &quot;Os0t9Mjm7FhPemzN0uQ8U7&quot;,
                &quot;version&quot;: 1,
                &quot;updatedAt&quot;: 1346642155713,
                &quot;guid&quot;: &quot;e-06R5_d_FfHXKHSCx-ky4&quot;,
                &quot;ffRefs&quot;:
                    [
                        {
                            &quot;name&quot;: &quot;theater&quot;,
                            &quot;type&quot;: &quot;FFO&quot;,
                            &quot;url&quot;: &quot;/ff/resources/Theaters/h3uX2Gt1j74w4yYbcifNq6&quot;
                        },
                        {
                            &quot;name&quot;: &quot;film&quot;,
                            &quot;type&quot;: &quot;FFO&quot;,
                            &quot;url&quot;: &quot;/ff/resources/Films/KG09l8GvwRc9pUzXGMTEJ4&quot;
                        }
                    ],
                &quot;createdBy&quot;: &quot;Os0t9Mjm7FhPemzN0uQ8U7&quot;,
                &quot;createdAt&quot;: 1346642155713,
                &quot;datetime&quot;: 1315094400000,
                &quot;clazz&quot;: &quot;Showing&quot;
            }
        ],
    &quot;statusMessage&quot;:&quot;Retrieved 1 resources from /ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4&quot;
}
</pre>
</div>
</div>
<p>The response includes the object itself (in &#8216;result&#8217;), and includes the URIs for any references (in this case, there are two). The FatFractal SDKs would then retrieve the referenced objects (requires a minimum of two additional queries, plus even more if these objects contain references or grabbag items themselves). That makes for a lot of round trips for the queries which can be expensive and adversely impact your application performance.<br />
<a name="get-more-for-less"></a><br />
<h4>Get More for Less</h4>
<p>Now you can access the entire datagraph from the object instance at a specified depth by adding the <strong>depthRef</strong> (depth for references) and <strong>depthGb</strong> (depth for grabbags) parameters:</p>
<p><a href="http://telluride.fatfractal.com/tff39/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4?depthRef=1&#038;depthGb=1">http://telluride.fatfractal.com/tff39/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4<strong>?depthRef=1&#038;depthGb=1</strong></a></p>
<p>This will return the object AND all of the object&#8217;s REFERENCES and GRABBAGS that the user has permission to read in a single response.</p>
<p>The response will now look like this&#8230;<br />
<h6 class="toggle"><a href="#">Click to see response</a></h6>
<div class="toggle_content" style="display: none;">
<div class="block">
<pre class="brush: jscript; title: ; notranslate">
    &quot;result&quot;:
        [
            {
                &quot;ffUserCanEdit&quot;: false,
                &quot;ffUrl&quot;: &quot;/ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4&quot;,
                &quot;qa&quot;: false,
                &quot;ffRL&quot;: &quot;/Showings&quot;,
                &quot;updatedBy&quot;: &quot;Os0t9Mjm7FhPemzN0uQ8U7&quot;,
                &quot;version&quot;: 1,
                &quot;updatedAt&quot;: 1346642155713,
                &quot;guid&quot;: &quot;e-06R5_d_FfHXKHSCx-ky4&quot;,
                &quot;ffRefs&quot;: 
                    [
                        {
                            &quot;name&quot;: &quot;theater&quot;,
                            &quot;type&quot;: &quot;FFO&quot;,
                            &quot;url&quot;: &quot;/ff/resources/Theaters/h3uX2Gt1j74w4yYbcifNq6&quot;
                        },
                        {
                            &quot;name&quot;: &quot;film&quot;,
                            &quot;type&quot;: &quot;FFO&quot;,
                            &quot;url&quot;: &quot;/ff/resources/Films/KG09l8GvwRc9pUzXGMTEJ4&quot;
                        }
                    ],
                &quot;createdBy&quot;: &quot;Os0t9Mjm7FhPemzN0uQ8U7&quot;,
                &quot;createdAt&quot;: 1346642155713,
                &quot;datetime&quot;: 1315094400000,
                &quot;clazz&quot;: &quot;Showing&quot;
            }
        ],
    &quot;references&quot;:
        [
            {
                &quot;ffUserCanEdit&quot;: false,
                &quot;filmType&quot;: 0,
                &quot;ffUrl&quot;: &quot;/ff/resources/Films/KG09l8GvwRc9pUzXGMTEJ4&quot;,
                &quot;director&quot;: &quot;Ben Affleck&quot;,
                &quot;ffRL&quot;: &quot;/Films&quot;,
                &quot;country&quot;: &quot;U.S.&quot;,
                &quot;version&quot;: 1,
                &quot;updatedBy&quot;: &quot;Os0t9Mjm7FhPemzN0uQ8U7&quot;,
                &quot;guid&quot;: &quot;KG09l8GvwRc9pUzXGMTEJ4&quot;,
                &quot;updatedAt&quot;: 1346472626252,
                &quot;filmDescription&quot;: &quot;While 50 Americans are held hostage by the Ayatollah Khomeiniâ€™s Revolutionary Guard, six U.S. Embassy employees hiding at the Canadian ambassadorâ€™s residence in Teheran stage a daring escape.Â â€œExtractionâ€ expert Tony Mendez (Ben Affleck) enlists a veteran Hollywood make-up expert and producer (John Goodman and Alan Arkin, each giving disciplined comic performances) to create a sham sci-fi movie epic in the hopes of finding a way out of the country. Affleck directs with formidable precision and documentary-style immediacy, intercutting between turf battles between the CIA and Washington diplomats, the chaotic street violence during Iranâ€™s revolution and the black comedy of spies pretending to be Hollywood types. This is thrilling, nail-biting entertainment.\nIn person: Ben Affleck&quot;,
                &quot;duration&quot;: 120,
                &quot;title&quot;: &quot; SNEAK: Argo&quot;,
                &quot;ffRefs&quot;: [],
                &quot;createdBy&quot;: &quot;Os0t9Mjm7FhPemzN0uQ8U7&quot;,
                &quot;createdAt&quot;: 1346472626252,
                &quot;madePossibleBy&quot;: &quot;&quot;,
                &quot;year&quot;: 2012,
                &quot;actors&quot;: &quot;&quot;,
                &quot;clazz&quot;: &quot;Film&quot;
            },
            {
                &quot;ffUserCanEdit&quot;: false,
                &quot;ffUrl&quot;: &quot;/ff/resources/Theaters/h3uX2Gt1j74w4yYbcifNq6&quot;,
                &quot;ffRL&quot;: &quot;/Theaters&quot;,
                &quot;version&quot;: 1,
                &quot;updatedBy&quot;: &quot;Os0t9Mjm7FhPemzN0uQ8U7&quot;,
                &quot;guid&quot;: &quot;h3uX2Gt1j74w4yYbcifNq6&quot;,
                &quot;updatedAt&quot;: 1346359016787,
                &quot;createdBy&quot;: &quot;Os0t9Mjm7FhPemzN0uQ8U7&quot;,
                &quot;address&quot;: &quot;&quot;,
                &quot;createdAt&quot;: 1346359016787,
                &quot;name&quot;: &quot;Chuck Jones Cinema&quot;,
                &quot;capacity&quot;: 500,
                &quot;longitude&quot;: -107.8478,
                &quot;latitude&quot;: 37.9361,
                &quot;sponsorString&quot;: &quot;&quot;,
                &quot;shortName&quot;: &quot;Chuck Jones&quot;,
                &quot;clazz&quot;: &quot;Theater&quot;
            }
        ],
    &quot;statusMessage&quot;:&quot;Retrieved 1 resources from /ff/resources/Showings/e-06R5_d_FfHXKHSCx-ky4&quot;
}
</pre>
</div>
</div>
<p>As you can see, the response includes the object itself (in &#8216;result&#8217;), but additionally, all objects referenced or contained in grabbags have been retrieved as well. </p>
<p>In your client code, using the methods provided in the various SDKs, the REFERENCE and GRABBAG items are automatically incorporated into your client object model, but now these are populated with a single request.</p>
<p>For more info on references, see the <a href="http://fatfractal.com/docs/data-modeling/#references" title="References Docs" target="_blank">docs here</a>.</p>
<p>Have fun!</p>
<p>Kevin</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-retrieve-an-object-graph-in-a-single-query-with-fatfractal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FYI &#8211; get all your data in one click from FatFractal</title>
		<link>http://fatfractal.com/prod/fyi-get-all-your-data-in-one-click-from-fatfractal/</link>
		<comments>http://fatfractal.com/prod/fyi-get-all-your-data-in-one-click-from-fatfractal/#comments</comments>
		<pubDate>Fri, 08 Mar 2013 15:28:23 +0000</pubDate>
		<dc:creator>Gary Casey</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[datagraph]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[privacy]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=10343</guid>
		<description><![CDATA[As a developer, I want to be able to export all my data (and I mean ALL my data) with one click so that I can do whatever I want to with my data, including moving to another provider &#8211; it is MY data after all. I was asked by @objclxt a couple of days ago if he could export ...]]></description>
			<content:encoded><![CDATA[<p><strong><br />
<em>As a developer, I want to be able to export all my data (and I mean ALL my data) with one click so that I can do whatever I want to with my data, including moving to another provider &#8211; it is MY data after all.<br />
</em></strong><br />
I was asked by <a href="https://twitter.com/objclxt">@objclxt</a> a couple of days ago if he could export his data stored in FatFractal with one click. At the time, we had always generated an export of the data for customers upon request, which is fine, but not what developers want. When someone asks for functionality that I know ought to be there, I get a bit antsy, so I decided that I had put that important piece of functionality off for too long, promised Nick a 1-day turnaround, and set about it.</p>
<p>Twelve hours of coding and testing, eight hours of sleep, and then another 3 hours running our release candidate smoke tests later, the good news was that it worked &#8211; and so it was deployed to production.</p>
<p>How it works:</p>
<p>From the console list of your applications, you will now see a link that says “export my data”. When you click on it, you will see an alert that tells you that your data is being exported and you will receive an email with a link to a zip file with your data.</p>
<p>Note: the request requires authentication/ authorization for the application as does the export link in the email, which is both ephemeral and is of course an SSL link for security purposes.</p>
<p>So &#8211; we export a zip that contains a number of .json files (one for each of your collections with all of the object data that they contain). The object data also contains all the references to other objects, a collection for your GrabBag references, including BackReferences, and of course we also export all of your blob data in the export.</p>
<p>Give it a whirl and let us know what you think!</p>
<p>Gary</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-get-all-your-data-in-one-click-from-fatfractal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FYI &#8211; Queries that will make you smile! FatFractal&#8217;s natural language queries are very cool.</title>
		<link>http://fatfractal.com/prod/fyi-queries-that-will-make-you-smile-fatfractals-natural-language-queries-are-very-cool/</link>
		<comments>http://fatfractal.com/prod/fyi-queries-that-will-make-you-smile-fatfractals-natural-language-queries-are-very-cool/#comments</comments>
		<pubDate>Mon, 04 Mar 2013 16:46:08 +0000</pubDate>
		<dc:creator>Kevin Nickels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[datagraph]]></category>
		<category><![CDATA[queries]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=10169</guid>
		<description><![CDATA[As a developer, I really want to be able to get the data back from my API in a single request so that my application performs better and I don&#8217;t get socked with excessive API requests that result from &#8220;chatty&#8221; APIs. One of the things that developers love about FatFractal is the way that you can construct queries that can ...]]></description>
			<content:encoded><![CDATA[<p><strong><br />
<em>As a developer, I really want to be able to get the data back from my API in a single request so that my application performs better and I don&#8217;t get socked with excessive API requests that result from &#8220;chatty&#8221; APIs.<br />
</em></strong></p>
<p>One of the things that developers love about FatFractal is the way that you can construct queries that can get you to what you want in a single round-trip.</p>
<p>First, the basics &#8211; FatFractal queries&#8230;</p>
<ol>
<li>&#8230;are written in an easy to create, easy to read, natural language style.</li>
<li>&#8230;can be chained together to filter the results to only the results you want in a single request.</li>
<li>&#8230;are able to &#8220;walk&#8221; your object graph in both directions.</li>
<li>&#8230;provide the best of relational capabilities without the complexity.</li>
<li>&#8230;are constructed as strings, not proprietary query objects.</li>
<li>&#8230;includes a very useful random operator that for some reason, nobody else seems to offer.</li>
</ol>
<p>Let&#8217;s say that you have movie <strong>Star</strong>, <strong>Movie</strong> and <strong>Theater</strong> objects and their respective collections (<strong>Movies</strong>, <strong>Stars</strong> and <strong>Theaters</strong>) and you want to get all the theaters that are showing movies that have a particular star acting in them within a defined distance from the user. The following explains how you can create a query string that can return that in a single request/ response to illustrate the power of nesting queries in a single construct:<br />
<strong><br />
<em>/Stars/(firstName matches &#8216;(%3Fi)milla&#8217; and lastName matches &#8216;(%3Fi)jovovich&#8217;)/BackReferences.Movies.stars/()/BackReferences.Theaters.movies/(distance (location, [57.5833, 3.8667]) lte 5000)?sort=rating desc, name asc&amp;count=5&amp;first=0<br />
</em></strong></p>
<p>Creating or reading FatFractal queries goes left to right, with query constituents enclosed in parentheses with &#8220;traversals&#8221; and queries separated by forward slashes. So, breaking down the query above into pieces:</p>
<ul>
<pre class="fancy_code_box">/Stars/(firstName matches '(%3Fi)milla' and lastName matches '(%3Fi)jovovich')
</pre>
<p>The first part (a query) will get the movie star(s) (<strong>Star</strong> object) from the <strong>Stars</strong> Collection with the <strong>firstName</strong> member &#8216;Milla&#8217; <em><strong>and</strong></em> the <strong>lastName</strong> member &#8216;Jovovich&#8217;, using regular expressions that compare while ignoring case (requires proper encoding of the Java regex mode modifier ?i for ignore case to be added as %3Fi) and a boolean operator (and) to ensure a complete match. Note: we now have a set of <strong>Star</strong> objects, probably with a single object.</p>
<pre class="fancy_code_box">/BackReferences.Movies.stars
</pre>
<p>The second part (a traversal) will then get all the <strong>Movie</strong> objects that she starred in based on the BackReferences from the <strong>Movie</strong> objects in the <strong>Movies</strong> Collection to the star in the <strong>Stars</strong> Collection. Note: we now have a set of <strong>Movie</strong> objects.</p>
<pre class="fancy_code_box">/()
</pre>
<p>The third part (a query) is an empty query operator that says that will use the entire set returned by the traversal.</p>
<pre class="fancy_code_box">/BackReferences.Theaters.movies
</pre>
<p>The fourth part (a traversal) will then get the <strong>Theater</strong> objects from the <strong>Theaters</strong> Collection that are showing movies that Milla Jovovich starred in from the BackReferences from the <strong>Theater</strong> objects in <strong>Theaters</strong> Collection to the above set of <strong>Movie</strong> objects in the <strong>Movies</strong> Collection. Note: we now have a set of <strong>Theater</strong> objects, which is what we want.</p>
<pre class="fancy_code_box">/(distance (location, [57.5833, 3.8667]) lte 5000)
</pre>
<p>The fifth part (a query) will then filter that set of <strong>Theater</strong> objects by geolocation that are within 5 kilometers of the user.</p>
<pre class="fancy_code_box">?sort=rating desc, name asc
</pre>
<p>The sixth part (a sort) will then sort them first by the <strong>rating</strong> member of the <strong>Theater</strong> objects in descending order, second by <strong>name</strong> member of the <strong>Theater</strong> objects in ascending order.</p>
<pre class="fancy_code_box">&amp;count=5&amp;first=0
</pre>
<p>Lastly, we then limit the result set of <strong>Theater</strong> objects to the first 5 items or less.
</ul>
<p><a name="summary"></a><br />
<h4>Summary:</h4>
<p>So, basically we start from a <strong>Star</strong> object in the <strong>Stars</strong> Collection, walk the datagraph to <strong>Movies</strong> using a BackReference, then walk the datagraph again to <strong>Theaters</strong> using another BackReference, and then filter the set of <strong>Theater</strong> objects further based on location, order the results by both the rating and name member values and limit the number of responses to a specified maximum count. Voila &#8211; you get what you want, ordered as you want, all in one go with a single, easy to understand query &#8211; this simply cannot be done with any other BaaS provider.</p>
<p>Also, let me point out the <strong>random</strong> operator in the FatFractal query language as it is an example of a very common use case. </p>
<p>Let&#8217;s say you want to retrieve a random movie <strong>Star</strong> from the <strong>Stars</strong> collection. The query looks like this:</p>
<pre class="fancy_code_box">
"/Stars/(guid eq random(guid))"
</pre>
<p>This is incredibly useful as otherwise, you would have to retrieve the entire set of Star objects from the Stars collection over the wire and then pick a random one from that set in your client code. Easy enough to program, but grossly inefficient in terms of client resources and network performance. Otherwise, you could *probably* retrieve a random item with two queries &#8211; first, by querying the collection to get a count, and if the API has an ordered ID (as many do), then you could generate a random ID in your client code and fetch that one (hoping that it has not been deleted). At any rate, getting a random object from a collection is a very common use case and I do find it bizarre that nobody else support this as easily as FatFractal does and forces you to use very inelegant client solutions.</p>
<p>One more point to make is that queries can be used in the context of GETS as well as within Server Extensions and Event Handlers.</p>
<p>All for now &#8211; have fun with your queries!</p>
<p>Kevin</p>
<p>For more information on FatFractal Query language, the <a title="FatFractal Query Language Reference" href="http://fatfractal.com/docs/reference/#query-language" target="_blank">docs are here</a>.</p>
<p>For more information on how to write queries with FatFractal, the <a title="Query Reference" href="http://fatfractal.com/docs/queries/" target="_blank">docs are here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-queries-that-will-make-you-smile-fatfractals-natural-language-queries-are-very-cool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FYI &#8211; You can run batch routines (CRON) jobs on FatFractal</title>
		<link>http://fatfractal.com/prod/fyi-you-can-run-batch-routines-cron-jobs-on-fatfractal/</link>
		<comments>http://fatfractal.com/prod/fyi-you-can-run-batch-routines-cron-jobs-on-fatfractal/#comments</comments>
		<pubDate>Mon, 25 Feb 2013 20:41:08 +0000</pubDate>
		<dc:creator>Kevin Nickels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[Event Handlers]]></category>
		<category><![CDATA[ffdl]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=10042</guid>
		<description><![CDATA[As a developer, I want to be able to schedule code to run periodically on my backend so that I can clean up my data, generate reports or any other function that is not generated by an event or API call. In addition to Event Handlers which execute based on data events and Server Extensions that execute on an API ...]]></description>
			<content:encoded><![CDATA[<p><strong><br />
<em>As a developer, I want to be able to schedule code to run periodically on my backend so that I can clean up my data, generate reports or any other function that is not generated by an event or API call.<br />
</em></strong><br />
In addition to Event Handlers which execute based on data events and Server Extensions that execute on an API call, FatFractal also supports running backend code on a periodic basis using our Schedule Code capability.  Any number of functions can be defined that execute on defined schedules. This has many applications from data administration to reporting, there really is no limit to what you can do with this.</p>
<p>Scheduled Code is defined in the same manner as Event Handlers and Server Extensions in your FFDL (<a href="http://fatfractal.com/docs/reference/#ffdl" title="FFDL Reference Docs" target="_blank">what’s this?</a>). You can define as many scheduled code events to be executed as you wish very easily as follows:</p>
<pre class="fancy_code_box">
SCHEDULE &lt;task name> &lt;schedule> AS &lt;script type>:&lt;script text>
</pre>
<p>Where schedule is given in CRON format:</p>
<pre class="fancy_code_box">
&lt;minute (0-59)&gt; &lt;hour (0-23)> &lt;day of month (1-31)> &lt;month (1-12)> &lt;day of week (0-6)>
</pre>
<p>For example, if I want to send out a daily report that lists the number of users for my cool new app, I would create a function like this in a file (here called EventHandlers.js):</p>
<pre class="brush: jscript; title: ; notranslate">
ff = require('ffef/FatFractal');
exports.userReport = function() {
    var n = ff.getArrayFromUri(&quot;/FFUser&quot;).length;
    var msgSubject = &quot;Application user total daily report&quot;;
    var msgString = &quot;You now have &quot; + n + &quot; users loving your application&quot;;
    ff.sendEmail({
        host: &quot;&lt;mailserver&gt;&quot;,   port: &quot;&lt;port&gt;&quot;,
        auth: &quot;&lt;true|false&gt;&quot;,   authPort: &quot;&lt;port&gt;&quot;,
        username: &quot;&lt;username&gt;&quot;, password: &quot;&lt;password&gt;&quot;,
        from: &quot;&lt;fromAddress&gt;&quot;,  to: &quot;&lt;toAddress&gt;&quot;,
        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
    });
}
</pre>
<p>And, then to schedule this be sent out daily at midnight, the FFDL would be:</p>
<pre class="fancy_code_box">
SCHEDULE UserReport 0 0 * * * AS javascript:require('scripts/EventHandlers).userReport();
</pre>
<p>That’s it &#8211; an approach that is very consistent with everything else which allows you to easily schedule any code that you like to execute on a defined schedule.</p>
<p>For more details on FFDL, the <a href="http://fatfractal.com/docs/reference/#ffdl" title="FFDL Reference" target="_blank">docs are here</a>.</p>
<p>For more details on Scheduled Code, the <a href="http://fatfractal.com/docs/custom-code/#scheduled-code" title="Schedule Code Reference" target="_blank">docs are here</a>.</p>
<p>Have fun!</p>
<p>Kevin</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-you-can-run-batch-routines-cron-jobs-on-fatfractal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FYI &#8211; FatFractal Server Extensions lets you extend your API with any function that you want</title>
		<link>http://fatfractal.com/prod/fyi-fatfractal-server-extensions-lets-you-extend-your-api-with-any-function-that-you-want/</link>
		<comments>http://fatfractal.com/prod/fyi-fatfractal-server-extensions-lets-you-extend-your-api-with-any-function-that-you-want/#comments</comments>
		<pubDate>Thu, 21 Feb 2013 19:50:25 +0000</pubDate>
		<dc:creator>Kevin Nickels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[ffdl]]></category>
		<category><![CDATA[server extensions]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=9974</guid>
		<description><![CDATA[As a developer, I want to be able to add any function without limitation to my API so that I can&#8230; do just about anything! As Gary mentioned in his post about the origins and future of FatFractal’s NoServer - “The cloud should&#8230; Not prevent me from doing anything else that I want to do” Server Extensions are, essentially, a ...]]></description>
			<content:encoded><![CDATA[<p><strong><br />
<em>As a developer, I want to be able to add any function without limitation to my API so that I can&#8230; do just about anything!<br />
</em></strong><br />
As Gary mentioned in his <a title="PaaS? BaaS? What?" href="http://fatfractal.com/paas-baas-what/" target="_blank">post</a> about the origins and future of FatFractal’s NoServer -</p>
<p>“<strong><em>The cloud should</em></strong>&#8230; Not prevent me from doing anything else that I want to do”</p>
<p>Server Extensions are, essentially, a means to extend your API with any kind of function that you desire. Server Extensions accept data as needed, execute any code that you want and return a broad set of return types (JSON, HTML) allowing virtually unlimited capabilities for your backend. They are easy to create, and you can add as many as you wish.<br />
<a name="what-can-i-do-with-a-server-extension"></a><br />
<h3>What can I do with a Server Extension?</h3>
<p>The uses for Server Extensions are very broad, but a few examples are:</p>
<ul>
<li>Aggregate data on the fly without corrupting your data model.</li>
<li>Access other backend services (e.g. salesforce, sap, etc.), then transform/ return the results.</li>
<li>Data management/administrative functions.</li>
<li>Manipulate and return HTML, images, videos, documents or any other MIME type.</li>
</ul>
<p><a name="extending-your-api"></a><br />
<h3>Extending your API</h3>
<p>Accessing a server extension is as simple as naming it in your FFDL (<a href="../docs/reference/#ffdl">what’s this?</a>), which will provide URI access to this particular function.</p>
<pre class="fancy_code_box">
CREATE EXTENSION /extension_name AS javascript:require ('scripts/MyExtensions.js').function_to_be_executed();
</pre>
<p>This will add a new URI endpoint to your application that looks like:</p>
<pre class="fancy_code_box">https://mydomain.fatfractal.com/ff/ext/extension_name</pre>
<p>When that URI is called, the function <code>function_to_be_executed</code> that is in the file <strong><em>MyExtensions.js</em></strong> in the ff-scripts directory will be called. Any provided parameters or data are made available to the function as well. You also have the option to declare the function to be secured (default) or add UNSECURED which allows a non-authenticated user to call the function as desired.<br />
<a name="passing-in-data"></a><br />
<h3>Passing in Data</h3>
<p>There is a wealth of data from a request that is made available to a Server Extension, including:</p>
<pre class="fancy_code_box">
httpMethod: the HTTP method (eg. GET, POST, PUT, DELETE, HEAD)
httpRequestUri: the request URI, relative to your application’s base URL
httpParameters: A map of the request parameters
httpHeaders: A map of the request headers
httpCookies: For convenience, a map of the cookies from the Cookie request header
httpContent: A map corresponding to the JSON content supplied in the request body, if any
ffUser: the guid of the logged-in user
</pre>
<p>This means that you can process according to the httpMethod used, pass in data as httpContent or as URL parameters and authenticate based on the user making the request &#8211; in short, you have a lot of flexibility on getting what you want into a Server Extension.<br />
<a name="return-types"></a><br />
<h3>Return Types</h3>
<p>You also have control over what gets returned by the extension, including the following:</p>
<pre class="fancy_code_box">
result: the data or content that you wish to return
responseCode: the appropriate http response code
statusMessage: an informational status message useful for debugging
mimeType: the MIME type of the response content
</pre>
<p>One of the most useful abilities that Server Extensions provide is the additional return MIME types that are supported. For example, you could create an image resizing service and set the MIME type of the return (e.g. “image/jpeg” or “image/png”). Or, you could read an html template file, replace elements to personalize it and return a web page (“text/html”). And, of course, you can always return data as well (“application/json”), which is the default.</p>
<p>You can also implement as much error handling as you want based on what data is received as well as the result of the operation itself. For example, checking for required information and returning an appropriate error code with a message that you want.</p>
<p>The following example of an extension that validates a user registration from a link shows a number of these features in use:</p>
<pre class="brush: jscript; title: ; notranslate">
exports.verifyRegistration = function() {
    var data = ff.getExtensionRequestData();
    var hc = require('ringo/httpclient');
    var r = ff.response();
    // check if user guid provided
    var guid = data.httpParameters['guid'];
    if (! guid) {r.result = null;
        r.responseCode = &quot;400&quot;;
        r.statusMessage = &quot;ActivationRequest guid not supplied&quot;;
        r.mimeType = &quot;text/html&quot;;
        return;
    }
    // check if activationRequest exists
    var activationRequest = ff.getObjFromUri(&quot;/ff/resources/ActivationRequest/&quot; + guid);
    if (! activationRequest) {
        var htmlContent = hc.get(ff.getHttpAppAddress() + '/validateuser.html').content;
        htmlContent = htmlContent.replace(&quot;___SUBJECT___&quot;, &quot;ERROR&quot;);
        htmlContent = htmlContent.replace(&quot;___MESSAGE___&quot;, &quot;The validation request for this account no longer exists. &quot;;
        htmlContent = '' + htmlContent;
        r.result = htmlContent;
        r.responseCode = &quot;404&quot;;
        r.statusMessage = &quot;ActivationRequest could not be found&quot;;
        r.mimeType = &quot;text/html&quot;;
        return;
    }
    // check if user exists
    var user = ff.getUser(activationRequest.userGuid);
    if (! user) {
        r.result = null;
        r.responseCode = &quot;404&quot;;
        r.statusMessage = &quot;User could not be found&quot;;
        r.mimeType = &quot;text/html&quot;;
        return;
    }
    // checks passed - now create the welcome html from a template and return
    user.active = true;
    ff.updateObj(user);
    ff.deleteObj(activationRequest);
    r.responseCode = &quot;200&quot;;
    var htmlContent = hc.get(ff.getHttpAppAddress() + '/validateuser.html').content;
    htmlContent = htmlContent.replace(&quot;___SUBJECT___&quot;, &quot;Thank You!&quot;);
    htmlContent = htmlContent.replace(&quot;___MESSAGE___&quot;, &quot;Your account has been activated.&quot;;
    htmlContent = '' + htmlContent;
    r.result = htmlContent;
    r.statusMessage = &quot;User now activated&quot;;
    r.mimeType = &quot;text/html&quot;;
}
</pre>
<p>Hope you find this useful&#8230;</p>
<p>Kevin</p>
<p>For more information about Server Extensions, <a href="../docs/custom-code/#server-extensions">see the docs here</a>.</p>
<p>For more information about FFDL, <a href="../docs/reference/#ffdl">see here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-fatfractal-server-extensions-lets-you-extend-your-api-with-any-function-that-you-want/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FYI &#8211; FatFractal provides an amazingly flexible event model for your business logic (when foo changes, do bar)</title>
		<link>http://fatfractal.com/prod/fyi-fatfractal-provides-an-amazingly-flexible-events-model-for-your-business-logic-when-foo-changes-do-bar/</link>
		<comments>http://fatfractal.com/prod/fyi-fatfractal-provides-an-amazingly-flexible-events-model-for-your-business-logic-when-foo-changes-do-bar/#comments</comments>
		<pubDate>Tue, 19 Feb 2013 17:13:32 +0000</pubDate>
		<dc:creator>Kevin Nickels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[Event Handlers]]></category>
		<category><![CDATA[ffdl]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=9750</guid>
		<description><![CDATA[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 ...]]></description>
			<content:encoded><![CDATA[<p><strong><br />
<em>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.<br />
</em></strong><br />
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.<br />
<a name="business-logic"></a><br />
<h3>Business Logic</h3>
<p>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.</p>
<p>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.</p>
<p>Maybe there is a better way&#8230;</p>
<p>As Gary writes in his <a href="http://fatfractal.com/paas-baas-what/" title="Gary writes about the origins of NoServer" target="_blank">blog</a> about the origins of NoServer -</p>
<p>&#8220;The cloud should:</p>
<ul>
<li>Store and retrieve my objects.</li>
<li>Securely – permissions and security should be robust and at a fundamental level.</li>
<li>Efficiently – with easy to create queries that get me what I want.</li>
<li>Execute code on the backend when my data changes (events).</li>
<li>Not prevent me from doing anything else that I want to do.&#8221;</li>
</ul>
<p><a name="event-handlers-user-stories"></a><br />
<h3>Event Handlers/ User Stories</h3>
<p>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.</p>
<p>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 &#8211; very cool!</p>
<p>For example:<br />
<em><br />
<strong>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.<br />
</strong></em></p>
<pre class="brush: jscript; title: ; notranslate">
exports.validateOrder = function() {
    var order = ff.getEventHandlerData();
    if (!order.amount || (order.amount &lt;= 0) {
        throw {statusCode:400, statusMessage:'An order amount greater than zero is required'};
    }
}
</pre>
<p><em><br />
<strong>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.<br />
</strong></em></p>
<pre class="brush: jscript; title: ; notranslate">
exports.alertBigOrder = function() {
    var order = ff.getEventHandlerData();
    if (order.amount &gt;= 5000) {
        var user = ff.getObjFromUri(&quot;ff/resources/FFUser/&quot; + order.createdBy);
        var name = user.firstName +  &quot; &quot; + user.lastName;
        var msgSubject = &quot;Woo Hoo - you got an order for &quot; + order.amount;
        var msgString = &quot;Order &quot; + order.amount + &quot; was created by &quot; + name;
        ff.sendEmail ({
            host: &quot;&lt;mailserver&gt;&quot;,   port: &quot;&lt;port&gt;&quot;,
            auth: &quot;&lt;true|false&gt;&quot;,   authPort: &quot;&lt;port&gt;&quot;,
            username: &quot;&lt;username&gt;&quot;, password: &quot;&lt;password&gt;&quot;,
            from: &quot;&lt;fromAddress&gt;&quot;,  to: &quot;&lt;toAddress&gt;&quot;,
            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
        });
    }
}
</pre>
<p><a name="controlling-your-event-handlers-with-ffdl"></a><br />
<h3>Controlling your Event Handlers with FFDL</h3>
<p>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 <a href="http://fatfractal.com/docs/reference/#ffdl" title="FFDL Reference" target="_blank">this?</a>). So to define the two functions above in your FFDL, you just add the following:</p>
<pre class="fancy_code_box">
CREATE HANDLER validateOrder PRE ON /Order CREATE AS javascript:require ('scripts/MyEventHandlers.js').validateOrder();
</pre>
<p>This means that the validateOrder() function will be called when a new order is <em>Created</em>, but before the Order is actually stored (PRE). This ensures that the order has all the requisite info and prevents storing zombie orders.</p>
<pre class="fancy_code_box">
CREATE HANDLER alertBigOrder ASYNC ON /Order CREATE AS javascript:require('scripts/MyEventHandlers.js').alertBigOrder();
</pre>
<p>This means that when a new order is <em>Created</em>, an alert will be sent via email Asynchronously, but only after the PRE event is cleared.</p>
<p>So &#8211; 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 &#8211; there are some things that need even more, and that is where Server Extensions come to bear. Will post about those soon.</p>
<p>Happy coding!</p>
<p>Kevin</p>
<p>For more information about Event Handlers, see <a title="Event Handlers Reference" href="http://fatfractal.com/docs/custom-code/#event-handlers" target="_blank">here</a>.</p>
<p>For more information about FFDL, see <a title="FFDL Reference" href="http://fatfractal.com/docs/reference/#ffdl" target="_blank">here</a>.</p>
<p>See Gary’s blog post about the origins of NoServer <a title="PaaS? BaaS? What?" href="http://fatfractal.com/paas-baas-what/" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-fatfractal-provides-an-amazingly-flexible-events-model-for-your-business-logic-when-foo-changes-do-bar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PaaS? BaaS? What?</title>
		<link>http://fatfractal.com/prod/paas-baas-what/</link>
		<comments>http://fatfractal.com/prod/paas-baas-what/#comments</comments>
		<pubDate>Thu, 14 Feb 2013 19:36:10 +0000</pubDate>
		<dc:creator>Gary Casey</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[baas]]></category>
		<category><![CDATA[crud]]></category>
		<category><![CDATA[datagraph]]></category>
		<category><![CDATA[Event Handlers]]></category>
		<category><![CDATA[paas]]></category>
		<category><![CDATA[server extensions]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=9803</guid>
		<description><![CDATA[Lots of people ask about the origins of NoServer, which is what we call FatFractal&#8217;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 ...]]></description>
			<content:encoded><![CDATA[<p>Lots of people ask about the origins of NoServer, which is what we call FatFractal&#8217;s BaaS module.</p>
<p>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 &#8211; 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.</p>
<p>The 90% boiled down to the following. <b><i>The cloud should:</i></b></p>
<ul>
<li>
Store and retrieve my objects.
</li>
<li>
Securely &#8211; permissions and security should be robust and at a fundamental level.
</li>
<li>
Efficiently &#8211; with easy to create queries that get me what I want.
</li>
<li>
Execute code on the backend when my data changes (events).
</li>
<li>
Not prevent me from doing anything else that I want to do.
</li>
</ul>
<p><br/><br />
The last point is <em><strong>really important</strong></em>! 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&#8217;t want it. So by June 2012 we had built enough to trial with customers &#8211; who loved it! &#8211; we launched our public beta in September, worked through the kinks in Oct-Dec <img src='http://fatfractal.com/prod/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  and we are now really focussed on getting the word out.</p>
<p>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.</p>
<p>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).</p>
<p>IMHO &#8211; 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 &#8220;BaaS&#8221; stuff, then I should be able to.</p>
<p>So &#8211; in a nutshell, what we have so far built into NoServer is:</p>
<ul>
<li>
CRUD persistence
</li>
<li>
SDKs that operate at the data level and do not encroach into your code unnecessarily.
</li>
<li>
Amazingly straightforward modelling of your object graph&#8217;s relationships
</li>
<li>
Natural language, chained queries nested as deep as you want.
</li>
<li>
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&#8217;t enough (which, so far, has been incredibly rare)
</li>
<li>
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 <a href="http://ringojs.org/documentation">RingoJS</a> 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&#8217;s datastore.
</li>
<li>
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
</li>
</ul>
<p><br/><br />
We&#8217;re pretty flexible at the server-side already, and I think you&#8217;ll agree we&#8217;re already better than (or *at least* as good as!) our BaaS competitors, but there&#8217;s lots more to come. Here&#8217;s a list of some of what&#8217;s coming over the next couple of months!</p>
<ul>
<li>
Greatly enhanced and pluggable authentication framework so that you can script integration with pretty much whatever 3rd-party identity / authentication cloud you like
</li>
<li>
Event Handlers for GET requests, and &#8216;virtual&#8217; collections
</li>
<li>
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)
</li>
<li>
Enabling integration between NoServer and Rails backends. This is a big step towards completing our vision &#8211; 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
</li>
<li>
Allowing use of NodeJS modules in your NoServer server-side scripting <em>expected end April</em></p>
<li>
Full support for NodeJS applications on the FatFractal PaaS, and integration between NoServer / Node / Rails / Servlets modules in your app&#8217;s backend
</li>
</ul>
<p><br/><br />
I hope that you like what we have built &#8211; would very much appreciate your feedback.</p>
<p>Cheers,</p>
<p>Gary</p>
<p>In case you&#8217;re curious &#8211; NoServer is a tribute to the <a title="No Chamber and No Ship" href="http://en.wikipedia.org/wiki/No-ship#No-chamber.2FNo-ship" target="_blank">no-ship</a> in Frank Herbert’s most excellent Dune series.</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/paas-baas-what/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FYI &#8211; With FatFractal you can send text or html emails programmatically using our JS Server-side SDK.</title>
		<link>http://fatfractal.com/prod/fyi-with-fatfractal-you-can-send-text-or-html-emails-programmatically-using-our-js-server-side-sdk/</link>
		<comments>http://fatfractal.com/prod/fyi-with-fatfractal-you-can-send-text-or-html-emails-programmatically-using-our-js-server-side-sdk/#comments</comments>
		<pubDate>Thu, 14 Feb 2013 19:20:06 +0000</pubDate>
		<dc:creator>Kevin Nickels</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[FYI]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[server extensions]]></category>
		<category><![CDATA[server-side js sdk]]></category>

		<guid isPermaLink="false">http://fatfractal.com/prod/?p=9763</guid>
		<description><![CDATA[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 I actually find it a bit odd that there are still so many uses for email in the context of an application these days, and anyone who knows me understands ...]]></description>
			<content:encoded><![CDATA[<p><strong><em>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<br />
</em><br />
</strong><br />
I actually find it a bit odd that there are still so many uses for email in the context of an application these days, and anyone who knows me understands I am not a big fan of email <img src='http://fatfractal.com/prod/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>All personal sentiments aside, the FatFractal Server-Side JS SDK makes it really easy to send out emails programmatically from your backend.<a name="text-only-emails"></a><br />
<h4>Text-only emails</h4>
<p>The <strong>sendSMTPEmail</strong> method (<a href="http://www.fatfractal.com/prod/linked_files/FF-Javascript-Server-SDK-2073/global.html#sendSMTPEmail" title="FF JS Server Side SDK sendSMTPEmail" target="_blank">docs</a>) 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 &#8211; say an Order, is received by your app.</p>
<p>First, define an EventHandler (<a href="http://fatfractal.com/prod/docs/custom-code/#event-handlers" title="FDDL Docs" target="_blank">what’s this?</a>) 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 (<a href="http://fatfractal.com/prod/docs/reference/#directory-layout" title="Scaffolding structure" target="_blank">more about this</a>), in this case we will call it <strong>EventHandlers.js</strong>.</p>
<pre class="brush: jscript; title: ; notranslate">
function notifyNewOrder() {
    var order = ff.getEventHandlerData();
    var user = ff.getObjFromUri(&quot;ff/resources/FFUser/&quot; + order.createdBy);
    var name = user.firstName +  &quot; &quot; + user.lastName;
    var msgSubject = &quot;New Order notification&quot;;
    var msgString = &quot;Order &quot; + order.amount + &quot; was created by &quot; + name;
    ff.sendSMTPEmail(&quot;&lt;mailserver&gt;&quot;, &quot;465&quot;, &quot;true&quot;, &quot;465&quot;, “&lt;username&gt;”, “&lt;password&gt;”, “&lt;fromAddress&gt;”, “&lt;toAddress&gt;”, msgSubject, msgString);
}
</pre>
<p>In your FFDL (<a href="http://fatfractal.com/docs/reference/#ffdl" title="FFDL Documentation" target="_blank">what’s this?</a>), you then define your EventHander like this:</p>
<pre class="fancy_code_box">
CREATE HANDLER notifyNewOrder ASYNC ON /Order CREATE AS javascript:require ('scripts/EventHandlers.js').notifyNewApp();
</pre>
<p><a name="html-emails"></a><br />
<h4>HTML emails</h4>
<p>The <strong>sendEmail</strong> method (<a href="http://www.fatfractal.com/prod/linked_files/FF-Javascript-Server-SDK-2073/global.html#sendEmail" title="FF Server-Side JS SDK sendEmail Docs" target="_blank">docs</a>) 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 &#8211; we will send out </p>
<pre class="brush: jscript; title: ; notranslate">
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:&quot;&lt;mailserver&gt;&quot;, 
            port:&quot;&lt;port&gt;&quot;, 
            auth:&lt;true/false&gt;, 
            authPort:&quot;&lt;port&gt;&quot;,
            username:&quot;&lt;username&gt;&quot;, 
            password:&quot;&lt;password&gt;&quot;,
            from:&quot;&lt;fromAddress&gt;&quot;, 
            to:user.email, 
            subject:subject,
            text:text, html:html
        };
        emailData = JSON.parse(JSON.stringify(emailData));
        ff.sendEmail(emailData);
    } catch (error) {
        throw &quot;Caught exception: &quot; + error + &quot; while sending email&quot;;
    }
}
</pre>
<p>And, include the FFDL for this EventHandler as well.</p>
<pre class="fancy_code_box">
CREATE HANDLER validateUser POST ON /FFUser CREATE AS javascript:require ('scripts/EventHandlers.js').sendWelcomeEmail();
</pre>
<p>The above makes use of a function called <strong>getHtmlWelcomeMessage</strong> 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.</p>
<pre class="brush: jscript; title: ; notranslate">
function getHtmlWelcomeMessage (user) {
    var hc = require('ringo/httpclient');
    var htmlMessage = hc.get(ff.getHttpAppAddress() + '/welcome_email.html').content;
    htmlMessage = htmlMessage.replace(&quot;___FIRST_NAME___&quot;, user.firstName);
    htmlMessage = htmlMessage.replace(&quot;___LAST_NAME___&quot;, user.lastName);
    return '' + htmlMessage;
}
</pre>
<p>That&#8217;s it &#8211; super easy to send email content to your users or for internal notifications/ reports or whatever you want!</p>
<p>Happy coding!</p>
<p>Kevin</p>
<p>For more details about FFDL, the documentation is <a href="http://fatfractal.com/docs/reference/#ffdl" title="FFDL Reference" target="_blank">here</a>.</p>
<p>For more details about the Server-side JS SDK, the documentation is <a href="http://www.fatfractal.com/prod/linked_files/FF-Javascript-Server-SDK-2073/global.html" title="FF Server-Side JS SDK Reference" target="_blank">here</a>.</p>
<p>For more about EventHandlers, the documentation is <a href="http://fatfractal.com/prod/docs/custom-code/#event-handlers" title="Event Handers Reference" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://fatfractal.com/prod/fyi-with-fatfractal-you-can-send-text-or-html-emails-programmatically-using-our-js-server-side-sdk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
