You may have noticed that we’ve built up a pretty extensive array of software drivers to access our API. I’d like to take a few moments to provide insight into our driver strategy and the lessons that have informed it.
First and foremost: we anticipate virtually all developers will prefer to use a driver when we’ve made it available. The core API exists as a neutral layer to support our drivers, and as a mechanism to fall back on when the language you are using doesn’t have an available driver. Our reason for providing drivers is to make it easier for you to write code, and for us to help you with your code if things go awry. Another way to think about it is like connecting Java to a SQL database: once someone has written a stable JDBC driver, most users would take advantage of that driver rather than writing their own.
We released our “V3” API about a year ago. Early on, most users were left to writing their own code to connect to our API from within the platforms they were using. We did a lot of question answering, question asking, and debugging of both our code and our customers’ code. We also gave a survey to our developers to answer basic questions like what languages they were developing in and what features related to our core offerings were most important to them. Based on our survey results (see chart, below), we introduced our first set of “drivers” for the most common development platforms among our developer base about six months ago.
Survey question: Which of the following are you using (or planning to use) to connect to the Factual API?
Since then, we’ve had time to reflect and refactor, as well as to expand our coverage to a lot of other languages. Here’s some of what we learned along the way.
Documentation by example is everything
Developers don’t like to read long documents and usually skip to the example section, if there is one. Hopefully our documentation reflects this lesson. If not, let us know! Aside from packing our core API with lots of examples, we’ve made sure that each driver is also abundantly packed with language specific code examples. In the case of iOS, we even provided an entire working sample app to look at.
Our API has been growing by leaps and bounds
In fact, our API has been growing faster than our resources for updating drivers can keep up with. To solve this, we implemented our “raw request” functionality in every driver – guaranteeing that there is always a way to make your requests, even for features that are barely out of the starting blocks. The raw request feature in each of our drivers provides a barebones manner to make an arbitrary Factual API request with a handful of request parameters. You provide the endpoint you are hitting, a map of parameters, and your API key. We take care of the encoding, OAuth and everything else to make sure the request gets to Factual, and that any error in doing so is handled cleanly. While this doesn’t always offer the same level of convenience as a dedicated function might (e.g., some of our drivers have a row filter construction set for generating really sophisticated filter objects), it guarantees that you can make any currently unsupported request with relative ease.
Make it easy to hone in on where things break
There’s a lot to the Factual stack. When you connect your code to Factual, one of the most important things is making sure that we can quickly conclude whether a bug is manifested in one of our drivers, your code or configuration, or our core API. All our drivers have debug modes that dump as much helpful information as available, and we try to include more than enough in our API error responses to help piece together what has really gone wrong.
Each programming language may have a different way of doing things correctly.
The Ruby Way isn’t necessarily compatible with the Zen of Python. Some languages make multi-threaded automatic garbage collection easy. Some, not so much. We’ve strived to be consistent with the expectations of each developer community, rather than forcing consistency internally across drivers.
Sometimes you need to go it alone
Determining what should be provided as syntactic sugar in a driver rather than trusted to developer creativity and coding skills is sometimes difficult. Adding code to our wrapper might not produce enough value or flexibility for our developers, and introduces the possibility of a new debugging point. We’ve tried to stay on the side of providing driver functions that spare users from writing their own code to solve common operations that are at high risk for errors. For example when we introduced our new API, the overwhelming majority of errors users were hitting occurred in two places: OAuth signing their requests and encoding filter parameters. As a result, these were the most obvious places for us to provide initial value in our drivers. We’ve taken care of both of these tasks so our developers never have to.
On the other hand, we’ve repeatedly considered whether it would be a wise decision to add any number of convenient driver methods that connect one of the services in our Crosswalk data to the appropriate third-party API. For example, instead of just getting the Foursquare ID out of Crosswalk, we considered building a “checkIn()” method that would actually fetch the ID and do the whole dance for you. What we decided for now is that it’s a lot of trouble to build and support this functionality where it interfaces to a third party API and we’re likely to fall behind new functionality of that third party API over time. While we haven’t quite hit upon a hard rule on what features to directly support in our wrappers, we’re hammering it out and feel confident that our strategy is starting to produce a pretty balanced feature set.
We’re still learning!
Currently, the overwhelming majority of our user base is accessing our API using one of our language-specific drivers. We hope that developers are picking that path because it is the path of least resistence to getting started with Factual. If you aren’t using one of our drivers yet, we’d love to know why. You can give us your feedback here.