Chicken Scratches

Seven Deadly Annoyances of API Design

Designing an API is an art and a science. Many intelligent people have failed. Those who succeed do so by keeping in view the main goal of an API: to annoy the hell out of developers.

My brothers and sisters, to honor that noble-ish pursuit we gather together to enumerate (see what I did there) the Seven Deadly Annoyances of API design. I never thought I’d write a listicle, but at least it has an erudite religious reference in the title.

First, a couple rules: We’re talking about successful, working APIs here. So things like “it doesn’t work” or “it opens a massive security hole” don’t count as annoyances. Don’t take the word “deadly” literally. And APIs that no one uses are not qualified. No, failed APIs are not annoying, just bad. Here we discuss just the minor things. The minor, hair-pulling, keyboard-smashing, Urban-Dictionary-quoting annoyances we all know and despise.

Many of the examples come from Android, because that’s who most recently has the pleasure of annoying me, but I don’t mean to pick on them. They have no monopoly on these sins.

Annoyance the first – trsnss

Yes, name-ification of things is hard. Still, common sense could go a long way. You gotta hand it to the Unix folks for their heroic efforts to save a keystroke – why say dupe when we can save that valuable E and say dup?

Number two is related:

Annoyance the second – makingNamesMuchTooLongToBePractical

Apple, in contrast, gives us gems like

 

outputImageProviderFromBufferWithPixelFormat:pixelsWide:pixelsHigh:baseAddress:bytesPerRow:releaseCallback:releaseContext:colorSpace:shouldColorMatch:

Vexation number three – Using synonyms

Oh, Android, I’m looking at you.

Apparently there’s a difference between a “BlankActivity” and an “EmptyActivity.” What’s the difference? I once knew, but now I’m drawing an empty – I mean a blank.

Android gives us tool bars, which at some point got renamed app bars, also known as action bars, giving us lovely code like:

    // Set the toolbar as my app bar
    setSupportActionBar(myToolbar);

To abbreviate or not to abbreviate. That’s apparently not the question at the Googleplex. Por que no los dos? Cross reference getExternalDirectory and getExternalFilesDir. These return two different locations, by the way, because sometimes in a directory you want to store files, and sometimes you want to store… I dunno, something else.

What’s the difference between a tap and a touch? I have no idea (at least not on a phone), and neither does the Android design team, who also sometimes calls it a click.

Hey, what version are you running? Oh, it’s KitKat. Or is it 4.1? No, maybe it’s SDK version 19… Oh wait, those all mean the same thing. Good luck keeping them straight.

And a final Android example. Want to make a project asset available by URL? Simply put it in the /assets/ directory in your source tree and construct a URL starting with “file:///android_asset/”. Yep, one is plural, one is singular. One has android_ in front, one doesn’t. Why? Because they’re Google and they can do whatever the hell they want, that’s why. What are you gonna do, use FirefoxOS?

Annoyance the fourth – Poor (or absence of) documentation

Speaking of asset URLs, you won’t find out about them by reading the documentation, aside from an offhand mention of it on the WebSettings.setAllowFileAccess method – a method which has zero affect on whether you can access files this way. Yes indeed, the old semi-documented feature.

Then there’s the Context class. It’s the Kardashian of classes: no one is quite sure what it does, but it’s everywhere you look. No one knows why, but you need it for almost all API calls. So there’s that.

Want to add a toolbar/action bar/app bar to your Activity? Here’s how you do it using the backward compatibility library. What if you don’t need backward compatibility? Surely there’s a way to do that with the built in classes? Probably, but you won’t find that in the official documentation.

And speaking of backward compatibility…

Annoyance the 5.1beta3 – Version incompatibility

If you’ve developed for Android, you know. Oh, you know all right. I… I can’t even write about this. The memories are too raw. Just.. you know.

WHY DOES IT WORK ON KITKAT BUT NOT MARSHMALLOW OR JELLYBEAN?!?!?!?!?!?

Annoyance the 6 – Overcomplimification (easy things made hard!)

Ahh, Fragments, how I love to hate you. Here’s a real diagram from Android documentation:

 

Android Fragment Lifecycle

But worse than Fragments are Notifications. Check the Android documentation for the section “Creating a Simple Notification.” Just in case they weren’t clear how simple it is, they make sure to repeat the word in the first sentence: “The following snippet illustrates a simple notification.” Care to see this oh-so-simple code snippet?

 

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!");
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);

// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(
            0,
            PendingIntent.FLAG_UPDATE_CURRENT
        );
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());

 

Oh dear, I’m overwhelmed with the beauteous simplitude!

Just to rub it in, the Android documentationalists follow this up with “That’s it. Your user has now been notified.” Oh, that’s it! Wow, and here I thought there would be some code involved, but now that you’ve shown me this crystal clear 27-lines of beauty, I feel relievificated. And don’t forget to import the three class you need. Oh yeah, and if you want backwards compatibilitude, it’s a whole different set of classes, plus you upgrom your gradle file and and do something else I mean who cares it’s stupid i give up i quit ill be a bartender.

What?

Oh, and don’t forget to also copy-paste these 30 lines of XML into a completely different file.

Speaking of which, the final and seventh deadly annoyance of API design is…

7. XML

Enough said.