An application programming interface, or API, is described as “A set of functions and procedures allowing the creation of applications that access the features or data of an operating system, application, or other service.” Essentially any code you write which could be used or called from somewhere else is an API – If you program, then you are an API designer. Most well written code is modular, each module will have its own API, its own way to interact with that module. Useful modules will get reused and can become great time-saving assets and most of the time you will forget it’s even there, it will just do its job. Bad modules however will cause frustration, unneeded constraints and time loss and possibly just dumped all together.
Qualities of a Good API
- Easy to learn – It shouldn’t take you days just to work out what the API does or how to use/call it, it also shouldn’t take piles and piles of documentation just to “get started”.
- Easy to use – It shouldn’t take more time to setup and use your API than it would to just remake the functionality. APIs should just drop in and work without hours of hassle.
- Easy to extend – Your API will never do 100% of every possible scenario a developer has in their head so it should be open to reasonable extension.
- Easy to read – Both the public API and the documentation should be clear and easy to read and understand to help developers learn quickly and keep the API intuitive.
- Appropriate to audience – Most users will have a technical background so your API can have some complexity. But remember developers come with different levels of experience.
Characteristics of an API
- Granularity – I can do A or I can do BC.
- Redundancy – I can do A or B.
- Coupling – Doing A implies B.
- Retention – Doing A mirrors B.
- Flow Control – Doing A also invokes B.
None of these characteristics are inherently good or bad, they are all major parts of an API, each one has trade-offs, but they must be balanced depending on what you want from your API and what I’s trying to do. There will always be variance in how much of each should and is required and the more APIs you design and let loose, the more you will start to get a feel for which are good and bad for your/your customers’ requirements.
Designing an API
Start by gathering requirements for the API, what does it need to do? What should it do? You should have discussions with developers who would use the API to see what they want or believe it should do, don’t just tunnel-vision on what you believe it should do. Always try to keep an open mind, often you’ll get proposed solutions instead – some of which may be better than your own! It is your job to extract the true requirements of the API in the form of use-cases.
Start with a short specification, just a handful of stories. You want to get a feel for the API, completeness can come later. Get feedback from as many people as possible and listen to their criticism, if something comes up which people aren’t sure about or dislike, this could manifest as a massive frustration when trying to use the API later. Then begin to flesh out parts you are confident in with code. You should start writing to your API early and often, before you have even implemented the full API. This way you can start to get a feel for what works, what doesn’t work, what could cause frustrations in the future. Anything that feels a bit off or unnecessary or awkward to use, will cause endless frustration down the line when it comes to extending or maintaining the API, so it’s better to find and address those issues now before the API is released to the outside world. It also means you have lots of demonstratable usages/examples for the API which you can use to prove that it works the way it’s intended and being sold and also use as examples in documentation. Maintain realistic expectations throughout the design process, most API designs become over-constrained and you won’t be able to please everyone. Some people will always want an overly granular API, some people will want a single “go” button that does everything. Instead of focusing on a single person or user group, aim to displease everyone equally. You will make mistakes during the design of the API, as the way you envision it will tend to be different to how different types of people wish to interact or integrate with the API, plenty of real-world use will quickly show any severe issues, so expect the API to evolve over time.
General Principles
- API should do one thing, and do it well
- Functionality should be easy to explain
- If the module/function you are designing is hard to name, you should probably rethink it
- Be open to splitting and merging modules and re-designing large betters better
- API should be as small as possible
- API should satisfy its original requirements and nothing more
- You can always add to an API, but you can never remove once it’s in use
- Stable, useful functionality is more important than bulk
- Implementation should not impact API
- Implementation details confuse users and make changing the implementation harder later
- Do not over specify internal behaviours of methods
- Don’t let implementation details leak into API (through exceptions, I/O, etc)
- Minimize the accessibility of everything
- Code should be as private as private as possible
- Maximise information hiding
- Modules should be able to be used and tested independently
- Document everything!
- The only way to ensure your API continues to be used when you’re gone
- Prevents people coming directly to you first with issues
- Functionality, and more importantly intent, becomes clearly defined
Conclusion
API design is very rewarding, it improves the lives of end-users, companies, other developers and you always learn a lot in the process. API design is hard, it’s not something that you can do just by yourself, as most of the time it won’t ever be just you using it. There is never a right or wrong answer, all APIs have different requirements and types of users. Because of these, perfection is unachievable, but try anyway!