What API choice I ended up with!

So I previously wrote a blog called How to design API function that creates Something where I was exploring various API design choices for a new project I am working on for my company. The blog was a meandering through various different choices available for one of the fundamental questions in APi design – how should we create an object and return it to the user?

Since then, I’ve read the slides of the awesome Stefanus Du Toit from his CppCon2014 talk Hourglass Interfaces for C APIs – and this really blew my mind.

I’ve always disliked putting C++ code in headers instinctively, I really hate not allowing people to use whatever languages/bindings they want when interfacing with my code. Plus, for the products I work on for my company we have a lot of customers that want to use pure C – meaning a C++ header is just a write-off. While I could follow LLVM’s approach of generating a C++ header and then providing C bindings for it – I feel that this approach is always a hack (for instance, the LLVM C API will double allocate memory temporarily when returning char* strings from the C API as the C++ API that it calls has to use std::string, which then has to be converted to a malloc’ed string as the C API must call free() on the resulting data!)

For my approach, all functions are prefixed with an [identifier_] string, in this case we’ll use cat_ (I do like cats as an aside);

typedef int32_t cat_error;

typedef cat_type_s cat_type_t;

enum cat_error_e {
  cat_error_success        = 0,
  cat_error_failure        = 1,
  cat_error_spilt_the_milk = 2
};

cat_error cat_type_create(const char* name, uint8_t age, cat_type_t* out_cat_type);

All of the APIs in my code are following the above approach bar none. Every function returns an error, and the caller is expected to respond to that error, all in variables are specified first, then inout variables, and lastly out variables. All inout and out variables have their variable names prefixed with inout_ and out_ respectively.

While this might not be ideal to all out there, what it does allow me to do is enforce a consistent API design throughout the product, and allow for much of the code to be self documenting (an aside – I also heavily use Doxygen for my documentation so even though I’ve tried to make the code as plain-text readable as possible, there are also pretty docs created for scouring!).

So far this approach has been welcomed by the users of the API (getting good feedback already) – it also is allowing me to focus on providing the C API functionality first and foremost, but with a mind to also adding the C++ API above the C API on the client side like Stefanus talked about in his CppCon14 talk!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s