The Elements of APIs

Appendix: Versioning your API

Finishing your API is just the first step. Someday there will be new requirements and things will have to change.

You should avoid breaking changes at all costs. A breaking change is when something that worked yesterday doesn't work today. That might mean that an endpoint that used to return some data now returns nothing; it might mean that it still returns data, but the data is different in an incompatible way to the what was returned before. Changing one attribute called full_name into two attributes called first_name and last_name is a breaking change. Preserving full_name while adding first_name and last_name, such that I can ignore those new fields if I don't care about them, is a safe, non-breaking change.

If you're still in development and you absolutely know that you (or your team) are the only ones using the API, don't worry about breaking changes. But make sure that everyone is clear on exactly when you're crossing the threshold at which point things must always continue to work. In development, when a QA tester encounters a breaking change, they know exactly who to bother about reverting the change or describing how to work around it. In production, when your users encounter a breaking change, they're stuck.

In general, and whenever possible: only add, never remove. If you need to make a change, and that change can be satisifed by adding a new attribute or relationship to an existing resource, do it that way. If you definitely need to change the whole implementation for a resource that already exists, leave that resource alone and create a new one instead. Deprecate the creation of that old resource if you need, but try to leave the existing data readable if you can. If you can leave the old way functional, don't even deprecate. Make it clear in your docs that you recommend using the new version, and explain what the benefits are. If the client insists on using the old way, update the docs to explain what they're missing out on by doing so.

If you're creating a replacement resource, give it a descriptive name that is not dependent on the reader knowing about the resource it's replacing. "TaxableOrder" is a much better name than "NewOrder" or "Order2."

In your design phase, ask your stakeholders and domain experts about what they think is missing from this API (and the product it supports). Many things are probably missing for good reason, and this doesn't mean you're going to include them. But knowing what might be added down the line—in a year, or in fifteen years—can help you to name the things you have and leave space for the things you don't.