You have a limited number of resources that can work on any endeavor. Call it headcount. People who are excellent at creating user experiences, working with design, and polishing pixels are almost never excellent at building easy to use, scalable, and flexible APIs. And of course the reverse is even more true: plumbers can’t paint worth beans. If you choose to be both an app and a platform you will have half the great plumbers and half the great painters you’d have otherwise.
Charlie Kindel, in his post “Be Either an App or a Platform, Not Both”, points out the difficulties of trying to be both an application and a platform, much of which comes down to the difficulties of designing a platform, period. As he notes in the quote above, trying to satisfy both objectives dilutes your focus. Additionally, once your system is supporting external clients (where external is defined as any client that isn’t built and deployed contemporaneously with your system, i.e. external apps can be built by your co-workers), you now have additional constraints on your ability to change. As he states in another post, “Don’t Build APIs”:
- Principle 1: All successful APIs will be abused in ways you cannot anticipate.
- Principle 2: You will support a successful API forever.
In many cases, I would have to agree that choosing between the application path and the platform path is good advice. As is so often the case, however, I can think of an exception – enterprise applications. Many of the issues facing corporate IT departments stem from an isolationist architectural mindset and the attempt to graft interoperability onto those systems after the fact: data islands, inconsistent duplicate data, poor integration, and functionality gaps, not to mention the costs involved in attempting to resolve these myriad issues. This is not to say that these systems are immune to the agility and focus issues Charlie Kindel warned of, just that those dangers are far outweighed by the costs imposed by poorly connected applications in an enterprise environment that are simultaneously redundant and lacking in key capabilities.
Roger Sessions has addressed this at the macro level in a recent series of posts outlining his Snowman Architecture concept (Overview, Economic Benefits, Technical Benefits). In a nutshell, this architecture partitions the application and information architectures of an enterprise along the lines of the business architecture to create capability packages. Each of these packages (the snowmen) incorporates an integral services architecture to provide interoperability, as with any service-oriented architecture. The difference, in my opinion, is that partitioning according to business capabilities should highlight both accidental redundancy and gaps in service as well as ensuring coherent packages.
Whether or not an organization has achieved, or even embraced this type of enterprise-level IT architecture, an application’s architecture will determine how quickly it can adapt to changes in the business environment. Using layers to provide horizontal partitions is, in my opinion, a good strategy to promote flexibility. Combining layers with vertical partitioning by high-level concern, even if only logically rather than physically, will yield designs that are better able to be refactored as needed. I favor using message-oriented designs over which a service facade can be added if and when needed. Ideally, each increment of complexity that’s added should only occur in order to enable additional capability and should carry more benefit than risk.
As was noted above, supporting external clients poses greater challenges. Once an API is available, changes should be handled via strict versioning in order to avoid taking down its consumers. Attempting to coordinate synchronized releases (required if you make a breaking change to an existing service rather than adding a new one) is begging for problems, particularly if the clients are external to your organization. Coupling a strict versioning strategy with the Canonical Data Model pattern enables making changes internal to your application without disrupting external clients.
Designing applications that can also serve as components in an enterprise platform is doubtless more complex than designing a standalone one. The relevant question, however, is not whether complexity is added, but whether the complexity is necessary. Having many simple systems that play together poorly, if at all, can complicate the IT architecture of the enterprise and fail to adequately support business operations. Systems that are structured to enable interoperability will fit into an enterprise environment far easier than ones that have interoperability bolted on after the fact.
Re-posted from Form Follows Function