How dare you release a hard-to-test API. How dare you.

APIs make the world go 'round. Well, perhaps not literally, but APIs are the unseen connective tissue that lets web apps talk with other web apps.

As a Rails developer, I've worked with alot of APIs. Some are a pleasure to work with, like Stripe's. Its documentation is exemplary, which almost atones for how maddeningly complex its schema is (and how often it changes!).

Some, however, are less than pleasant to work with. Pivotal Tracker's is well laid out at first glance, but had a bunch of inconsistencies and gotchas that make you really read the fine print. Harvest's Forecast, as another example, pretends they don't even have one, leaving you to trailblazer through a thicket of exploratory curl requests until you figure out how to do the thing you want to.

I had the pleasure of attending Rails World 2024, and I particularly enjoyed Julia López's (Senior Software Engineer at Harvest) presentation on testing integrations. She gave us the real talk about the "good, the bad and the ugly" when it comes to testing API integrations in your web app. The high-level takeaway was: there is no silver bullet for testing API integrations. You can either mock them, record & replay them or test against the live API. Sometimes your circumstances will lend themselves to using all three of these approaches. It's always going to be a bit of a mess.

But having reflected on this a bit, I have decided that this is terrible. It is terrible that I have to endure so much ambiguity and busywork just for the privilege of connecting to another web service via API. In most cases, I'm actually paying to do so. How dare you???

Here's my strong opinion on APIs:

1. If you make an API available, you should also make a test API available, with well documented, predictable responses.
2. You should exempt requests to this test API from any rate limits or request quotas. Make it as static as you can, cache the hell out of it and make it free.
3. You should make sure that the test API's schema is always identical to the live one.

A test API lets developers build on your API with confidence. It relieves them from having to manually mock out dozens of dummy responses. It de-risks the practice of using a "live" API to perform tests. And, assuming you keep its schema in perfect parity with the "real" API, it provides an early alert if/when your schema changes, giving your developers a chance to adapt to its changes as a part of their normal CI routines.