Trial Wizards Leveraging Open Platform API

Petr Cvengros

We have a killer app program. For each vertical we offer an advanced, customer-proven pre-packaged solution that brings you best practices on the methodologies and KPIs in the given business. We wanted to bring the benefits of our apps to as many people as possible and give you a try-before-you buy experience of the GoodData apps. That’s why we built web-based trial wizards for our most popular apps:

These self-service tools guide you through a few simple steps:

  • You give us contact information, so that we can help you evaluate the app.
  • You grant us access to your data residing in the cloud (Salesforce or Yammer). Granting access is done in a secure way using OAuth - you don’t have to give us any passwords, you just give access to our app in the cloud. Permission can be revoked at any time.
  • For the sales app you also need to provide some basic information about your Salesforce implementation so that the wizard knows where to take the data from.
  • A background process downloads your data and loads it to the GoodData platform.
  • When everything is ready, we invite you to the GoodData project where you can get unprecedented insights to your data, analyze trends in ad-hoc reports and evaluate the app before you buy.

Wizzard

How we built it and why

The goal was to build it fast and agile so that we can iterate and incorporate feedback of different users as fast as possible. Even though the GoodData platform is very agile, we release major versions every month and new minor versions every other day, we decided to build the trial tools outside of the GoodData platform so that we could iterate even faster. When designing the trial framework, we had to make a few decisions that we’d like to share. We’d be thrilled if our process could motivate others to build something similar!

Language: Ruby

Nowadays building agile apps means using a dynamic typed scripting language. You can express more with less code. You don’t have to care about compiling your code and changing the code is generally easier. When building our trials we wanted to leverage the tools we already have: GoodData Ruby. That’s why we chose Ruby.

Architecture: Monolithic web app vs. REST API + JavaScript client

The next decision we had to make is whether to build a monolithic web application in a framework like Ruby on Rails or to build a Ruby backend covered by a REST API plus a purely javascript client for the user interface. Although we had much more experience with the first variant, we chose the second one. The reason was the fact that UI and backend functionality can be built separately (and that’s how GoodData platform is designed). Also, building an appealing user interface is nowadays easier in pure JavaScript frameworks than with JavaScript added to server-side generated html templates. Spoiler alert: this turned out to be a great decision.

When we came up with the first prototype of the Sales trial wizard it contained 5 steps on separate screens for mapping Salesforce data to the GoodData Sales app data model. After some internal testing and consulting our UX experts we decided to shrink the configuration steps to just one screen. With a monolithic web app this would mean rewriting most of the code as the presentation and logical layer are tightly coupled. In our case, we only had to tweak the JavaScript code to put all the steps to one route, the resources at the REST API didn’t need any change at all.

Another pro is writing tests - with our approach we could write a set of simple tests for each API resource without having to worry about the UI layer that is more likely to change over time. To build the REST API we used a ruby micro-library called Grape, it has all features one can ever need and its DSL is clear and crisp. For the frontend JavaScript app we used the Ember.js framework. It’s powerful, runs fast, and we already had some internal libraries built in it.

Deployment: Internal Infrastructure vs. Heroku Application Platform

When building an agile app, you want to be able to deploy new versions with one command in a matter of seconds. As we didn’t have resources to build continuous deployment for ruby on our own infrastructure so we decided to use Heroku, an application platform for cloud apps. After some configuration we could be sure that with a single git push, all the ruby code would get updated, our javascript would get minified, and after a few seconds trial users would be able to enjoy the new version. This is provided by using multiple buildpacks in our Heroku setup.

Another advantage is scaling - by adding a few web or worker nodes, we can accommodate as many users as we want.

As we share some API resources for all the trials, we use a single git repository for all trial wizards. Only the environment variables indicate which app is currently running. That way we can set up or tear down development environments in just a few minutes, using separate Heroku apps. Code sharing and agile deployment enabled us to come up with new app wizards quickly. For example, we prepared the wizard that builds Yammer Analytics within a week.

Background jobs: Resque

Sooner or later, every web app developer comes to a point where synchronous request processing by a web server is not enough. Some actions, as downloading data from external systems usually take a long time and the web server can’t wait with the response until they finish. At that point it’s necessary to employ another node (Heroku “dyno”) that performs the long actions and stores the results when ready. For background job processing, we used a ruby library called Resque. On top of that we built a REST API resource for starting an action and another one for getting the result of the action (or a response that the action hasn’t finished yet).

We had to do a few tweaks to make Resque work for us seamlessly. Some actions (e.g. data downloads) don’t have to fully employ the node, as they’re only waiting for another server to finish. For these type of tasks we introduced a special type of job that periodically checks status on the remote server without fully employing the node.

Another tweak we had to do is related to the way how Heroku handles job termination. For each job we had to implement a strategy how it should react when Heroku sends it a TERM signal. Most jobs are just enqueued again and the action is repeated. For the same reason we couldn’t expose the job identifiers from Resque on our REST API: when a job is re-enqueued it gets a new identifier and the old one isn’t valid anymore. To solve that issue we introduced a mapping layer between the Resque identifiers and identifiers exposed by the REST API. Before a job is terminated, it updates its Resque identifier in the mapping.

Summary

The way we built the trial wizard shows that powerful apps can quickly be built outside of the GoodData production environment on top of the platform API. Using different frameworks and services we were able to come up with an app that was developed rapidly, uses up-to-date technologies, and scales as needed. Special thanks to all teams and individuals that helped us along the way!

Most importantly, thanks to Open GoodData Platform API, everyone can implement an app like this! Check out our Developer Portal and API documentation for more information and resources.


About The Author

Petr Cvengros Petr Cvengros Product Manager, Expert Services - hacks on top of the GoodData Platform API to create new programs, make customers happier and consulting services more productive. Before joining GoodData, Petr worked in Deloitte Enterprise Risk Services as a consultant. Email petr.cvengros@gooddata.com

Dev's Newsletter

Subscribe Now