Author Archives: Derrick Ko

Kicksend Practices Part I – Backend and Web

Kicksend is a multiple platform application, we have clients on iOS, Android, OS X, Windows and the web. All of this is powered by a Rails backend, which we treat as an API server. Here are a couple of practices we have in play right now.

The Backend

(Taken by Tom Raferty)

Avoid to_json

Responses are the equivalent of views for your API; your presentation layer. Hence, you shouldn’t use to_json to generate your response, the same way you wouldn’t put presentation logic in your model. Use a templating system/builder like RABL (which we use) or Jbuilder.

Action cache

We use action caching, based on the principals of key based cache expiration. This keeps cache invalidation very simple for us as they auto-expire whenever an object or a collection is updated. We use a couple of helpers to simplify our cache key generation.

The Web App

The Kicksend web app is made with Backbone.jsHandlebars in Coffeescript. We treat it as a standalone entity, and it consumes our API the same way as our other apps do. There’s no special treatment.

Keep the UI responsive

As much as possible, keep your app responsive and don’t block the user. People have the expectation that rich clients are snappy. Some tips:

  1. Design your app such that you don’t have to use { wait: true }.
  2. Assume that the request will be a success, and have an error state with a retry otherwise.
  3. Load commonly used collections in the background, regardless of the page the user visits.
  4. Keep things asynchronous.

Modularize

Keep your models and collections independent from your views. This makes our views easily reusable (and even nestable). We instantiate individual models in our router and app wide collections on load, and never within the view. In the rare event you need to instantiate a model/collection from within a view, ensure that they are used only within the lifecycle of the view.

Have a single representation of each resource

For each resource (eg. api/lists/1), we maintain a single model representation of it as much as possible. This ensures that the right models are used by our views, so that the any model changes are appropriately reflected in the UI. We use our app wide collections to maintain the “gold” model representation of each resource. Here’s an example:

  1. You navigate to “kicksend.com/home#/lists/1/edit″ to edit your Family list.
  2. To reduce wait time, we make an API call to “/api/lists/1″, and instantiate a single List model – let’s called it Model 1. We then render the list edit page with Model 1.
  3. In the background, we load up our collection of all your lists (KS.lists), which will contain another model of your Family list – we’ll call this Model 2. The rest of the app operates off Model 2.
  4. Any changes to Model 1 is synced back to Model 2 within KS.lists.

Use a view manager

In a single page app, instantiating and destroying your view is important. Mismanagement can lead to a bloated DOM and stray event bindings. Taking a cue from Derick Bailey, we use a singleton to handle all view transitions and cleanups. The Kicksend app has two “containers” that we render views in – within the page or in a modal. With our View Manager, we can easily render any view in either container.

Over the next couple of months, we’ll be discussing more practices we use throughout the Kicksend ecosystem, so stay tuned. As always, we are always looking to improve and we love to hear any suggestions or improvements you may have!

Catch us on Twitter at @Kicksend and @derrickko. Sounds interesting? We’re hiring.

How we rewrote the Kicksend web app in one month

Startups have a phase where the first generation of the product has to make way for the second. In our case, we set out to create

  • a wonderful experience for our users
  • a faster, leaner front end code base
  • a great foundation to build out new features faster

And, those goals meant it was also time to rewrite part of our Kicksend stack.

Rewrites are strangely attractive. Developers love to work on a sparkling clean code base. But in reality, there’s much more to a rewrite beneath the surface. Like all those implementation subtitles and edge cases you took for granted.

Before jumping into a rewrite, start with the business and product considerations, because if a rewrite is the best path then with the right planning and approach, you’ll avoid a lot of pain.

Here’s what worked for us at Kicksend.

Be very clear of your goals

Rewrites can quickly balloon out of control. There will always be the tendency to throw in new features. So it’s important to keep the scope of the rewrite focused. Scope out a minimum viable rewrite – a great place to start would be hitting feature parity with the original version.

We set out to rewrite only the upper levels of our stack, and not the entire application (there was no reason to). In terms of changes, that meant we had three goals:

  1. a migration to a new database schema
  2. a refactored, new RESTful set of APIs
  3. a complete rework of the web application

With those goals in mind, we made sure to hammer out the scope and implementation of each item. We whiteboarded the schema migration, the APIs, and iterated on the new web application’s user-facing design before we wrote a line of code. After which, we split these items up into Pivotal Tracker stories.

From then on, we made it a point not to introduce any features that weren’t directly related to the implementation or didn’t fall in line with our goals, which worked well to curb feature creep.

Simplify

It’s a rewrite. Take the opportunity to simplify.

Each feature and technical decision that made it into our rewrite had to meet the following criteria:

  • simplified our technical implementation
  • improved user experience
  • boosted productivity

1) Cut out Features - Since we measure everything, deciding what to leave out of the rewrite was a straightforward, data-driven decision.

2) Optimized UX - An example of a feature that we did rewrite is “Lists.” In Kicksend, lists are great way to easily send files to private groups of people. We felt that this was a core experience of Kicksend, and we had to nail the user experience. With the rewrite we introduced more intuitive ways for our user to manage their lists and achieved simplification.

 

 3) Swap to Coffeescript – Using Coffeescript made this development simpler and fun, which in turn boosted our productivity. For the curious, the rest of our frontend stack consists of Backbone.js with Handlebars.

On balance, the scope of our rewrite actually turned out to be smaller than the original version.

Get it on production. Now.

Don’t do a waterfall-style “big bang” release. Don’t coop up your rewrite on a staging box, only to be deployed to production on release day. The quicker you can deploy an iteration of your rewrite to production, the easier your life will be.

We spent the first two weeks preparing our code base to accomodate the rewrite on production. That meant a whole bunch of chores like retrofitting our current APIs to write to the new schema, changing up the web application to use the new set of APIs, and migrating over to Rails’ asset pipeline. After all that, we were running our rewrite live in production, in parallel to the original version.

Results

  1. We continuously deployed (our usual cadence)
  2. We battle-tested our rewrite in production for a month and a half
  3. “Launching” just meant flipping a switch

Rewrites are tempting, but can also be deceptively complex. Don’t rush into one. Have a well thought out plan. It worked for us; we launched smoothly and right on schedule.

So check out our shiny new web app, or grab our mobile and desktop apps.

Catch us on Twitter at @kicksend and @derrickko. And join in the discussion on Hacker News.

PS. Sounds interesting? We’re hiring.