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.
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.
- 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
- 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
- Start with a Short Spec - 1 Page should be Ideal
- Extract true requirements out of proposed solutions
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.
Ideally, APIs should be small, simple, and clean. However, sometimes, it's easier and more rewarding to build something more general.
Don't surprise the user by the behavior of APIs.
For instance, the method name and its action should be aligned mutually.
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.
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.
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.
For instance, use Private modifiers for the variables thoroughly.
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.
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.
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.
A long list of parameter lists is often confusing and error-prone when similar typed.
Ideally, it shouldn't be more than 3-4.
For ease of use, we should keep the order of the parameters similar in various actions.
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.
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.
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.
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:
Please share your thoughts in the comments.
Thanks for reading!