API First! So We Decided on a Complete App Rewrite…

Greg Werner
IllumiDesk
Published in
6 min readNov 2, 2017

Our application and company has been through a lot of changes for the last 10 months. We wanted to share some of those experiences with you, as so many folks from the community have helped us through these exciting times.

A little history

We started the endeavor of creating a new data science platform during the Spring of 2016. We were data scientists and software engineers that became frustrated with how long it took to setup up environments that would support data science teams. In our opinion, it was all silly stuff too. Some tasks included:

  • Making sure we had EC2 instances with enough disk space and memory,
  • Making sure had all the right dependencies installed for our Jupyter Notebooks and R IDEs
  • Setting up and maintaining NFS
  • Staying up to date with the latest stable version of docker engine (you may remember how fast Docker was moving in 2016, it was kind of hard to keep up)
  • Making sure our integrations with Spark clusters were up to date
  • Double checking versions of CUDA drivers to ensure compatibility with the latest deep learning frameworks

The list went on and on. Surely we weren’t the only data science team burdened with these tasks, right? Well it turns out that many data science teams were having exactly the same problems, so we decided to build a standard platform so teams could get up and running with a few clicks.

Yay! We had an idea and had identified a need within the market, time to develop a proof of concept!

And that we did. From the early stages we decided on open sourcing our full stack (we’ll talk about why we decided to open source our full stack in a separate post). We built our app pretty fast, in about three months we had a solid, working version using a standard Flask stack. Actually we were quite proud of our first version, our stack ended up looking something like so:

First version of 3Blades app with standard Flask based stack

Then we decided to gage interest and launched a pre Alpha version of the product. And low and behold, interest was great.

Yay Part II! We had a good, working POC, time to mature the product!

Our version at the time was working quite well so we decided to build upon the POC. We worked really hard to make sure everything was well documented and organized. I must say the code itself was pretty good. Nice docstrings, good code coverage, DRY, SOC, … But as the product matured and as we started an engagement with our first large Pilot customer we encountered a sobering reality: our customers could not easily integrate with our product. Sure, we had an API. But every time we rolled out a new feature we had to manage Jinja2 templates plus the RESTful endpoints, separately. (Read: longer time to market and increased support costs).

Let’s just build this thing and sell it! We can fix it later…

Have you ever been in a situation where you knew the product wasn’t as great as it could be, but yet had to sell it and support it as if it were? We had been in these situations multiple times throughout our careers. Nevertheless, as is always the case in this industry, there were already other companies developing good data science platforms. We quickly came to realize that having a “me too” product was too risky.

Let’s talk ROI

Why is it so important for customers to be able to integrate with your product, quickly and securely? It pretty much all boils down to ROI. Let’s look at an example:

  • A customer invests 20,000 dollars on acquiring your product
  • The customer spends 3 months integrating the product with their systems, which translates into another 30,000 dollars of man hours
  • The manufacturer writes custom code to help with the integration efforts (read customer service will suffer down the line, likely impacting churn), which takes 1 month, which translates to another 10,000 dollars in costs
  • The project promises to save the company about 75,000 dollars

In this case, total investments from the customer are about 50,000 dollars, not including the opportunity cost of having custom code (we’ll leave this out of the equation but it’s still worth mentioning). If the customer saves 75,000 dollars from the investment, then ROI is something like:

ROI = (revenue — costs) / costs = 75K — 60k / 60k = 25%

Not bad! But wait, it could be much better. What if the above numbers were changed to look like so:

  • A customer invests 20,000 dollars on acquiring your product
  • The customer spends 1 month integrating the product with their systems, which translates into 10,000 dollars of man hours.
  • Zero custom code
  • The project promises to save the company about 75,000 dollars

ROI = (revenue — costs) / costs = 75K — 30k / 30k = 150%

This quick back of the envelope calculation makes it obvious that having a product that is easy to integrate wins almost every time.

API First! WTF is API First?

API first is integration first. Integration first for our customers and for ourselves. Easy integration helps with scale.

Integration is important for customers because it allows them to integrate with our platform quickly, without a lot of headaches. Let them decide how to spawn user servers and modify files. Would they like to use our front end? Cool. Would they rather use a custom front end instead? That’s cool, too. The most important element of having an API First design is reduced on-boarding time. That helps our bottom line as it allows us to implement and move on to the next customer, and helps the customer gut up and running faster.

Enter Django and ReactJS

There are lots of good backend frameworks that provide solid foundations for API first designs. Our goals were simple: re use as much of our code as possible and also move our front end to a JS framework that was performant and future proof. After a quick look at the alternatives, we settled on a standard Django stack with ReactJs. A move from Flask to Django is not earth shattering and we felt that ReactJs has a great ecosystem. Although we could have stuck with Flask’s RESTful extension to surface our app’s endpoints, we felt that Django was more suited to our needs.

After some pretty major refactoring, we ended up with a standard Django stack:

3Blades stack after refactor

You may be asking yourself why such the drama, the architecture looks almost exactly like our first version! Not so fast. That small change of hooking in all of our front end applications with the API is huge. We immediately started seeing benefits with:

  • Time to market for new features
  • Improved stability and reduced support costs
  • Improved documentation
  • Reduced customer on-boarding times

Closing Thoughts

If we had to do it all over again we would have considered this API First design from the prototype stage. But…looking back on our experience we are glad, in a sense, that we immersed ourselves with the Flask ecosystem and the Jinja2 templating framework. Because of our experience with Jinja2, in particular, we picked up Ansible and other DevOps tools much faster than if we had not had this experience.

In the end, we feel that constant experimentation and ‘throwing code away’ to build simpler, more robust solutions is a win in any one’s book.

If you’d like to try us out, feel free to Sign Up Here, it’s free for life and no credit card required.

--

--