Critique of Stripe’s Java APIs

I recently started looking at the Stripe APIs to add billing features to DripStat. Considering the API is Stripe’s interface, I was expecting a smooth sailing, well architected Java API to use. However, looking at the Java API docs, I couldn’t help but say something about the state of Stripe’s Java APIs.

Examples use everything except Java

It starts with the tutorial pages. There is an example in every language except… guess which one?

API that feels like Ruby/Javascript

But ignoring that, I started looking at the actual API reference docs. I stumbled across sample code like this:

Map planParams = new HashMap();
planParams.put("amount", 2000);
planParams.put("interval", "month");
planParams.put("name", "Amazing Gold Plan");
planParams.put("currency", "usd");
planParams.put("id", "gold");

Plan.create(planParams);

The ‘filling a hash map’ technique is littered throughout Stripe’s APIs. Its what you would use in weakly typed language like Ruby, Javascript, etc. Not in Java where you actually have type safety.

Here is how the above API should be:

Plan plan =
   new PlanBuilder()
       .setAmount(2000)
       .setInterval(Interval.MONTH)
       .setName("Amazing Gold Plan")
       .setCurrency(Currency.USD)
       .setId("Gold")
       .build();

Using the builder pattern makes the API type safe to use and easier to read.

Another example:

Plan p = Plan.retrieve("cpum8g");
Map updateParams = new HashMap();
updateParams.put("name", "New plan name");
p.update(updateParams);

Aside from the use of maps, it is unclear if the update() method updates the Plan object in place or returns a new, updated object.

A more elegant way is:


Plan p = Plan.retrieve("cpum8g");
Plan newPlan =
       new PlanBuilder()
         .setName("New plan name")
         .update(p);

Conclusion

This is not a critique of Stripe, the service. It is a very valuable service and should exist in every country. This is a critique of the Java API specifically. I hope this article will shed some light on it and they will improve it.

Update

Someone noticed…

If you run a startup or create things in general, watch Indie Game, The Movie. Jeremy Jahns does a great review of it.

Making Intellij IDEA perform better

Intellij by default runs on the Java 6 jvm it ships with. Install java 8 and use this guide to get Intellij to use it.

You will notice a performance boost due to the newer JVM. Especially so on the Retina Macbooks where the both the performance and the text rendering is greatly improved.

After all, Java 6 was released when there was no such thing as retina displays.

Tumblr - Not designed for blogging

The more I use Tumblr, the more I realize how ill suited it is for blogging. It feels more like a long form version of Twitter than blogging software.

This is evidenced by how the ‘Post’ buttons have you choose between Text, Image, Video, etc. A blog post would usually comprise of all of these elements combined.

Not designed for Long form posts

Wanna create a post with an embedded youtube video? You cant. Wanna create a post with lots of images? You can’t, because in a ‘text’ post, Tumblr will crop does images down to almost invisible sizes. Features like clicking on an image to show a larger version are non existent.

Even typographical elements like Headlines are non-existent from Text posts. You can directly edit the html/markdown to insert a h2 tag, but none of the default Tumblr themes will style it properly and the spacing around the heading will be wonky.

What other options are out there?

Since Tumblr is not a blogging platform per se, what other options are out there:

Wordpress

Too complex compared to alternatives. More for building websites than blogging.

Blogger

Ha. We are in 2014 now.

Medium

This seems nice but completely takes away your identity.

Ghost

Ghost seems to be the best choice currently. It looks beautiful and extremely simple to use. Is designed for long form writing. High profile bloggers like Coding Horror are using it. That said, the hosted version is paid. I still prefer this to the rest of the options.

Hyperlapse: Giant vs Startup

A week or so ago Microsoft research published a paper showing the mega cool Hyperlapse technology.

Today Instagram released a full working app that allows you to actually create them on your phone.

Famous’s Achilles Heel - Maps

While famo.us has cool demos and has great plans for the future to replace native mobile apps, the one place they really fall short is Maps.

A big reason to use a native app instead of a web page is to get fast, responsive maps. Unless either Google or Apple decides to implement their map using Famo.us APIs (which is not happening anytime soon), Maps will remain a big reason why you continue creating native apps.

The Invisible Skyscraper Of Software

Yesterday I was assembling an IKEA table. It was exhausting but felt extremely satisfying to see the physical table when it was built.

I make software everyday which in its size and complexity could be a skyscraper compared to that table. But it is invisible. Me or no one else can ever marvel at the beauty of that skyscraper I create.

Somehow assembling that table felt more satisfying..

Essential Gradle snippet for Intellij users

Intellij IDEA likes to create a bunch of directories for its own use. Since they are inside the project folder, they will clutter your ‘Project’ view in the IDE.

The official way to deal with these in Intellij is to select them and mark them as ‘Excluded’ so Intellij wont look at them and they wont clutter your views. However, if you have a Gradle project, Intellij ignores its own settings and those directories will magically reappear when you hit ‘Refresh’ in the Gradle view or reload your project.

After a ton of hair scratching, I reported this to Jetbrains and this is indeed a bug as of Intellij 13.1. The official workaround for this is to manually exclude the directories in Gradle itself using a snippet like this:

apply plugin: 'idea'
idea {
    module {
        excludeDirs += file('.idea')
        excludeDirs += file('out')
        excludeDirs += file('projectFilesBackup')
        excludeDirs += file('servercommon')
    }
}