Good API Design and Why It Matters?
Anshul Bansal
Posted on December 27, 2020
1. Overview
In this article, we'll discuss How to design a Good API and Why it matters to each of us (I'm talking to the Programmers/Developers)?
Note: This article is an excerpt of Joshua Bloch's talk - How to Design a Good API and Why it Matters?
I know many of us would've already seen that video. So, we'll be going through Josh's recommendations for a Good API design and touch our basics again. By chance, if you are new, feel free to explore his genius.
2. What is an API?
An API (Application Programming Interface) is a contract between the user and the software.
It's an interface for the user to interact with the software, perform actions, and exchange data in the prescribed formats.
It can be as simple as a few methods available in a class to as complex as the web services for the enterprise software.
3. Why it Matters to Us?
- Every programmer is an API designer
- Whether designing a class that performs some actions or implementing web services
- Public APIs are forever, so we get only one chance to get it right
- Once APIs are published in public, it's impossible to take them back
- A good API wins customers
- Assets for the corporates and lasts longer
- Improves code quality, reusability, and maintainability of the software
- Good design usually coincides with good performance
4. What is a Good API?
- Easy to learn
- Easy to use, even without documentation
- Hard to misuse
- Easy to read and maintain code that uses it
- Sufficiently powerful to satisfy requirements
- Easy to extend and evolve
- Appropriate to its audience
- Coexists peacefully with the platform
5. Tips for Creating a Good API
5.1. Get the Specs Right
- Start with a Short Spec - 1 Page should be Ideal
- Extract true requirements out of proposed solutions
5.2. API Should Do One Thing and Do it Well
Design and implement API keeping one problem in mind.
We shouldn't try to solve a lot of problems in a single API. Better, go with a set of APIs to address different needs.
For instance, the LocalDateTime and CompletableFuture classes in Java solve the problem of Date/Time and Asynchronous programming very well.
5.3. API Should be as Small as Possible but No Smaller
Ideally, APIs should be small, simple, and clean. However, sometimes, it's easier and more rewarding to build something more general.
5.4. Don't Violate the Principle of Least Astonishment
Don't surprise the user by the behavior of APIs.
For instance, the method name and its action should be aligned mutually.
5.5. When in Doubt, Leave it Out
It's always easier to add to the API (in further iterations). But, we can't remove anything from it once published - as APIs should honor the backward compatibility to avoid any hassle for the existing implementations of the consumer.
5.6. Never Leak the Implementation Details
When implementation details get leaked through documents, it's harder to change or modify the implementations later.
For instance, a user may rely on the implementation details and use them in the features. So, this could lead to disaster on the consumer side if the implementation modifies in the APIs.
6. Implementation Guidelines for a Good API
6.1. Naming Matter
Follow naming conventions diligently. Also, names and their behaviors should be consistent throughout.
For instance, the same name shouldn't mean different in the various parts of APIs.
APIs should read like prose and never astonish the consumer by their behaviors that go against their name.
6.2. Minimize Accessibility of Everything
For instance, use Private modifiers for the variables thoroughly.
6.3. Minimize Mutability
Without a good reason, we shouldn't keep our classes mutable.
Immutable classes are simple, concise, and doesn't need synchronization handling in the concurrent transactions.
6.4. Fail Fast
Report errors as soon as possible after they occur.
Usually, compile-time is the best, and that's why we should take advantage of generics/static typings.
6.5. Use Appropriate Parameter and Return Types
Consider specific parameter types over the String. The same goes with BigDecimal over float/double for the monetary values.
Also, try to use the same parameter/return types for similar data exchange.
6.6. Avoid Long Parameter Lists
A long list of parameter lists is often confusing and error-prone when similar typed.
Ideally, it shouldn't be more than 3-4.
6.7. Use Consistent Parameter Ordering Across Methods
For ease of use, we should keep the order of the parameters similar in various actions.
6.8. Avoid Return Types that Demand Exceptional Processing
For example, when dealing with the collection return type, the consumer shouldn't bother about handling a null value, which is prone to the NullPointerException. Rather we should return an empty collection.
6.9. Documentation Matters
Documentation is a must for a good API design, its popularity, and success.
We can see, all Java APIs and popular libraries are very well documented.
Therefore, we should document everything like class, interface, method, constructor, parameter, and exception. Also, we must state the preconditions, postconditions, and side-effects for any action/behavior.
At the same time, as we've discussed already, we should never document implementation details.
6.10. Test with Two-Three Plugins Before Release
We should test our APIs very-well before the release. For that, write two to three plugins for the APIs to make sure it will mostly behave as expected for future consumption.
7. Conclusion
In this article, we've seen a few recommendations for a Good API design, some tips and tricks for the implementation, and why it matters to us?
For Coding Best Practices take a look:
Coding Best Practices for Java Apps
Anshul Bansal ・ Nov 16 '20
Please share your thoughts in the comments.
Thanks for reading!
Posted on December 27, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.