You are making a small, harmless change to the code. You stop, you know that you'll upset someone. Have you ever felt this way? This is exactly what Hyrum's law states:
“With a sufficient number of users of an API,
it does not matter what you promise in the contract:
all observable behaviors of your system will be depended on by somebody.”
To understand it better, let's analyze the elements involved.
What is an API? An API is the boundary between the user and the product/service.
The API of a TV remote control is composed of its buttons. They are used by users who don't need to know what's happening inside the remote control. What happens inside the remote control is called "implementation". What's the advantage of this distinction? The advantage is that the implementation can change without the user having to worry about it.
The contract of an API is the set of guarantees about the product/service provided to the user.
Simply put, the remote control in question guarantees us to have an on/off button, two buttons to increase and decrease the volume, two buttons to switch to the previous and to the next channel.
Suppose the first implementation of the remote control doesn't have battery charge controls. When the charge is low, the remote control continues to work as long as you get close to the receiver. In the second implementation, the remote control stops working if the battery charge is less than 25%.
Even though these aspects are not covered by the contract, with a sufficiently large number of users, we will have the following scenario:
an user of the first implementation guesses that if the remote control doesn't work, he can approach the receiver to make it work. If the remote control continues not to work, then he must replace the batteries.
The same user, switching to the second implementation expects the same behavior. If the remote control doesn't work, he approaches the receiver to make it work. However, the remote control still doesn't work because in this case the implementation is based on the battery level and not the distance from the receiver. The user incorrectly concludes that the remote control or the receiver don’t work, but not that the batteries are dead.
That’s a case of Hyrum's Law: an API user is relying on an observable system behavior, even though the API contract doesn't guarantee it.
In software engineering, this law is also known as the "Law of implicit interfaces". It should be considered during the evolution of a system that needs to ensure backward compatibility. Both changes to the contract (explicit interface), and changes to other observable system behaviors (implicit interface) can break it.
The effects of this law can be mitigated in two ways: the API provider should limit exposure of observable system behaviors not described in the contract, and the user should rely only on the API contract. This makes it easier to introduce changes in a system.
Top comments (0)