Governing APIs after they Ship
Aidan Cunniffe 2023-10-13
One night I met a heart surgeon at a party and asked her what the hardest part of surgery was. She didn't even have to think about it: "the patient has to survive the procedure". Blood has to keep pumping, even when she's fixing the main pump. Improving our company's APIs presents us with similar challenges. If we could just turn everything off for a few months, start anew, and have our consumers stop using the old APIs, we could make so much progress -- at least we imagine we could. But we can't do that. Every so often we get to build net-new services and follow the best practices we came up with, but what about the APIs that have already shipped? How do we govern those?
Before you can start improving your APIs, you need to understand how they work today. What does each service do? What patterns are common between them? What has been working best for consumers? Having accurate documentation helps you make better decisions, saves developers time integrating, and helps you measure the effectiveness of your governance efforts.Documenting existing services with OpenAPI can take time, but it is worth doing.
If you do not want to document manually, you can try:
- Generating from your code types (this works better in some languages than others)
- Generating OpenAPI from your API tests
You end up with accurate documentation and a list of all the promises you made to consumers.
Your API is not code, it is a set of promises you make to each consumer. Once they integrate with your API, they expect it to keep working the way it did when they started to depend on it. Even if there are design changes that would make the API simpler, most consumers would rather you build a new API than break the existing one.
Inside large companies breaking changes happen all the time, especially between internal services. Developers are not trying to break consumers, they just do not realize a API change they made is breaking, or that they've made an API change at all. It's hard for many of us to imagine how a simple code change could impact our API's contract, and our consumer's code. AAutomation can help.
optic diff computes the API changes between two git branches, and checks if any of them are breaking. Teams run it in CI to catch breaking changes, before they ship:
Many API teams adopt a style-guide to help them ship more consistent APIs that follow their best practices. However, if you turn on style guides for existing APIs they will recommend making hundreds of changes to existing endpoints. Making these changes would take a lot of time, and introduce a ton of breaking changes. API Linting is not like code linting, fixing the issues they raise will often break the very APIs you are trying to improve.
What we need is a smarter linter tool, one that understands the API lifecycle and applies rules differently based on whether an API is new or already in production. That's why we build
optic diff. Optic will make sure new endpoints follow your latest standards without holding your legacy endpoints to the same standard. Your APIs will get a little better every day and keep moving towards your ideal, while keeping compatibility for existing consumers.
optic diff openapi.yml
# rules to apply to new endpoints
# rules to apply to existing endpoints and new endpoints
If you're interested in shipping better APIs and like what you have read about our approach to API governance, check out our docs or set up a call. We'd love to help you think through your API program.
I presented this post as a talk at API Days Paris, check it out here: