Adventures in Poorly Written APIs
I’m working with a library that I have been fighting with for the better part of three days now to try to get it to work.
The previous version of this library was actually very well written from an API perspective and well documented. The new version? Not so much.
But from this, I take away two lessons in API design.
Lesson 1: Don’t Use Dictionaries in Public APIs — ESPECIALLY for Required Data
The first mistake the API designers made in this case was exposing a “dictionary” in the public API.
This itself may not be all bad if the API is highly flexible and can accept many forms of requests, but if a public dictionary interface is required, then at least have the good judgement to provide a wrapper to populate those dictionaries.
But even the lack of usability is not as bad was having required data inputs passed to your service as dictionary entries. In other words, the service call won’t succeed without some sort of magical recipe of just the right metadata keys and values. If it’s a required piece of metadata, why not surface it as an actual parameter to the function?
Exposing dictionaries in public APIs is a terrible design idea which is as bad as APIs that require you to pass in XML strings (understood if it’s a must, but have the courtesy to provide downstream callers an API to serialize objects into that XML and don’t put required data into open ended inputs). They should be used infrequently and preferably wrapped by an abstraction layer.
Lesson 2: Don’t Require Your Caller to Keep Passing You Data You Handed Back
In this particular API, there is an initialization handshake with the server whereby large bits of system data are passed back to the caller.
For whatever reason, instead of simply handing a token back to the server, all (or part?? — again, it’s a magical incantation of sorts) of this metadata must be exchanged with the server to complete a request!
Why not provide a session key? A caller token? Something that the caller can use to represent this collection of system data instead of the full set of system data?
More to come, I’m sure of it, but this has been an interesting adventure in poorly written APIs.