What Is Gall's Law, and How Could It Direct API Design?

What Is Gall’s Law, and How Could It Direct API Design?

Posted in

Gall’s Law is an interesting concept with applications across many different fields. As a systems theory, it has proven time and time again to be an appropriate approach to building strong, resilient systems. In the modern tech field, it has inspired everything from microservices to agile development.

But what exactly is Gall’s Law? And who in the world is this Gall? In this article, we’ll dive into Gall’s Law and look at how it applies broadly and specifically within the web API space.

What Is Gall’s Law?

Gall’s Law is named after its author, John Gall. John Gall spent his career as a practicing pediatrician who also researched childhood behavioral and developmental issues. Much of this research focused on systems failures, the idea being that behavioral and developmental issues arose from systems that failed to adequately address their root causes, whether those systems be in childhood education, parental support, or even early medical preventative treatment.

From this research, Gall would go on to author General Systematics, a book that would offer practical systems designs principles based on his practice and research. This book laid out what engineers refer to as Gall’s Law, stating:

“A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.”

To simplify this statement, the basic argument is that no system is created perfectly from the get-go, and complex systems cannot be created from nothing. Every large system that works effectively and efficiently first started as a simpler, smaller one, and was iterated into the larger one as needs were increased and the overall demands of the system were changed.

Technical Implications of Gall’s Law: The Internet

So, what does Gall’s Law mean in the context of technical development? Perhaps the strongest example of where this law has successfully proven itself is the very medium through which you are reading this article — the internet.

In 1958, ARPA, or the Advanced Research Projects Agency, began to build a system of interconnected resources, technologies, standards, and methodologies with the aim of connecting computers and communication systems together. By 1967, this had flourished into ARPANET, a massive computer network that iterated upon its simple foundings to connect major think tanks and institutions together on one system. By the mid-1970s, these technologies had been iterated even further, with TCP/IP standards being developed and the term “internet” cemented in RFC 675: Internet Transmission Control Program, December 1974.

As additional technologies coalesced, the internet began to take shape, developing, iterating, and expanding to serve more clients and purposes. By the 1980s, the internet was spreading in both user base and complexity, adding additional functionality, form, and function, and by the late 1980s and early 1990s, commercial internet use began. Over the next twenty years, the internet would grow exponentially, supporting multimedia streaming, online shopping, infrastructure control, email, and so much more. The internet rapidly grew in complexity and use to the point that today it is almost globally ubiquitous.

Let’s stop and look at where the internet is today. The technologies are so diverse and unique now that there is no possible way developers of the original ARPANET (and its earlier predecessor technologies) could have possibly developed something to support these functions. If the designers of the internet had sat down from day one to design a system that supported anything and everything, the system would have been overly complex, resource intensive, and ill-defined. It could even be argued that adoption would have significantly lagged due to the over-general definition of its form and function.

This is a great example of Gall’s Law — the internet came from something simple and developed into a system that, while imperfect, is far more complex than the sum of its parts.

APIs, Microservices, and Decoupled Design

Gall’s Law is applicable to API design as well, and we have to look no further than the modern movement towards microservice-based development. Microservices development is the idea that software components should be broken into multiple parts, with each piece performing a specific thing. The opposite of this principle is monolithic development, wherein an application does everything in a singular vertical entity.

What does this look like in practice? Imagine we have an API designed to serve weather data to a user. If we were developing this API as a monolith, we would build everything in a singular service. The location data, the weather tracking systems, the caching for requests, any advertising systems, and authentication would all live in a singular code base in a single location.

There are a few difficulties with this kind of system. Firstly, it’s challenging to iterate upon. As the codebase does everything in a single code body, any change will affect the codebase as a whole. Would you like to change how the weather is displayed in the app, and perhaps support multiple degree formats? We not only need to change the degree code, but we also need to ensure that anything which interacts with this endpoint can support the change.

This iteration would touch many aspects of the codebase for something particularly small. Now, let’s imagine an even bigger change. What if we wanted to start connecting users to flight information if they’re looking up the weather in a far-away location? After all, those users might be interested in traveling to those locations, and this could be a huge potential revenue source if we integrate external partners. To do this, we’d have to change every aspect of the codebase, from how the weather is shown, how we lay out the screen, how we cache the requests to ensure that users don’t get the same data if they opt out, among other factors.

This is where the monolith becomes a problem. In a microservice-oriented solution, we are adopting Gall’s Law — the best system is going to be a simple system that iterates. In this spirit, a microservice approach would decouple the codebase functions into their own discrete microservices. The temperature service would be different from the user authentication service, which would be different from the location service, and so on. If we wanted to add on a new chunk of code or alter the functionality of existing code, it would be as simple as adding a new microservice and creating endpoints to connect it to existing services. In this way, we can iterate quicker and more cost-effectively.

More importantly, however, we are adopting a radical transformation in how we approach complexity. When building a monolith, you are attempting to develop a perfect state for your current requirements. The problem with a monolith comes when those current requirements change. In such a situation, microservices are the way to go. Rather than building for perfection from the ground up, iterating upon a proven simple but effective system will result in a more productive, scalable service.

Development Approaches and Paradigms

Interestingly, Gall’s Law has influenced more than just the approach to microservice design. It has influenced the practice of modern application development itself. One such influence can be seen in the concept of agile development.

Agile is, at its core, an argument for iterative approaches instead of releasing everything at once in a big release. Agile argues that discrete pieces should be developed to provide minimal functionality per the client expectations and the minimum viable product, and then should be iterated to provide additional form and function. In essence, you learn to walk before you run instead of immediately doing a marathon. While running a marathon without any prior training might be possible, it’s a more painful endeavor with higher costs.

This focus on discrete elements is certainly a paradigm shift from older waterfall development models. In the 1980s and 1990s, it wasn’t uncommon to go to a store and buy a software package with everything you needed on a single disk or diskette. While some support was provided, if the program needed iteration, you would have to wait for a second version or a massive update, which could take years. In the modern software landscape, users can receive updates to their core software as often as necessary, with basic versions iterating and developing over time. Most of the software we now use was released in a simple state that iterated upon success and proven usability to deliver a more comprehensive product.

The Death of Complexity?

This isn’t to say, of course, that there is never any place for a monolithic approach, or even an approach that focuses on solving a large problem in one go. There are some use cases where a monolithic, non-extensible solution flies against Gall’s Law. The reality, however, is that, even in those cases, trying to solve the whole problem in one shot is ineffective. Development should be broken into pieces and iterated upon to deliver the final product.

This is all to say that complexity has too often been linked to the first step of complexity in an overall system. There is an innate part of the human brain that says, “the first step is too simple, and too far away from the end goal, and we need to do more.” Gall’s Law is essentially a kind of speed bump in that process, arguing that even the most complex items should be broken into smaller parts that iterate and develop into more complex systems. This seeming incongruity between the first steps and the ultimate goal makes this law somewhat nuanced to understand and apply.

Conclusion

Gall’s Law is a law in the same way that Conway’s Law or Hyrum’s Law is — the theory is not set in stone but is helpful to consider when designing a solution. Adopting this mindset can help result in cheaper, more efficient, more effective development lifecycles, let alone software packages and web APIs.

Gall’s Law has proven itself useful across different types and implementations of systems worldwide, and it’s a wonderful tool to carry in your systems-planning toolkit. But what do you think of this law? Do you see any situations in which Gall’s Law is perhaps not useful? Let us know in the comments below!