|
|
|
|
|
by zemaj
4865 days ago
|
|
This is a great post. I'm currently building an API that's really inspired by Stripe's API. I'm trying to mimic a lot of these elements, from the easy authentication through to the really useful error messages. One of the things I'm not so sure about is the local bindings for each language. I'm tempted to just use off-the-shelf HTTP clients or a very thin wrapper in each language and write code snippets based on them. I'm not sure I see the value in writing full client bindings - I've often found it harder to use in many cases when I use these 'opinionated' bindings in the past. You often end up with a choice of entirely following the libraries views on error handling or digging around and breaking upgrades by modifying these libraries directly. I've always preferred much thinner wrappers that have no knowledge of the underlying API calls. Would love more opinions! |
|
As an API author, I think your goal should be to make interacting with your API as simple and robust as possible. The downside with just recommending off-the-shelf HTTP clients is that there's always a ton of logic (whether request formatting, error handling, or turning responses into first-class objects) that the vast majority of consumers of your API want and will have to write on their own. If you look at the internals of our bindings, a lot of the logic is around understanding exceptions (https://github.com/stripe/stripe-ruby/blob/master/lib/stripe...) or interstanding semantics of our API (https://github.com/stripe/stripe-ruby/blob/master/lib/stripe...), which are tasks that would take a newcomer a lot of time to get get spun up on.
There will always be frameworks where your bindings don't work (e.g. our Ruby bindings aren't compatible with EventMachine) or paradigms that they violate (e.g. using error return values in PHP rather than throwing exceptions). That's actually ok -- just because you can't support everyone doesn't mean you should support no one. Instead, we put a lot of effort into making our bindings compatible with as broad of a range of environments as possible (e.g. https://github.com/stripe/stripe-python/blob/master/stripe/_...).
So my advice would be write bindings which convert the semantics of your API to the consumer's language, but which constrain the consumer's application as little as they can. Even if people end up having to use a lower-level abstraction to talk to your API, they can probably steal code or ideas from what you've written.