Best Practices in Composable Enterprise Solution Implementation

This blog post presents my perspectives on best practices for implementing composable software solutions. This content is not for software vendors developing products for enterprise customers, but for those customers using those products to implement solutions. Conforming to these suggestions should help you to meet flexibility, scalability, productivity, reliability, maintainability, traceability, agility, and other objectives.

To repeat, these are my perspectives; I realize that some of these points may be controversial, and I encourage their discussion. If you have any additions, suggestions, or questions about this content, please comment on this blog post.

Business Logic Belongs in Systems, Not in Solutions

Business logic belongs in systems exposed as services, not in custom application code. Encapsulating logic in an application or rules engine makes it reusable by multiple consumers, such as all the various channels for delivering digital experiences (website, mobile application, kiosks, etc.). If you find yourself implementing significant logic in a point solution, consider encapsulating that functionality as a service. Solution logic should be specific to a solution, such as invoking a minimal number of services to implement the user interface.

Avoid Microservice Architecture

Microservice architecture is for products, not for solutions. Implement services at the level appropriate and required for your solution, not for every function of that solution. Excessively finite services complicate implementations and reduce performance, and generally do not add sufficient value to justify their use internally.

Avoid Direct Access to Vendor APIs

Avoid direct access to vendor APIs by implementing a software infrastructure layer between clients and the applications.

Avoid Working with Proprietary Vendor JSON Formats

Apply domain-driven design to your solution rather than focusing on the architecture of specific applications in your stack. For example, rather than implementing GraphQL queries in your solution, write a generic API that transforms requests from your solution to the formats required for specific vendors, and transform the results from those applications to a generic format for consumption by your solution.

Avoid Vendor Software Development Kits

Using Software Development Kits (SDKs) from vendors leads to tight coupling between your solution and the vendor’s application, which results in vendor lock-in.

Apply Established Software Architecture Principles

General design philosophies and principles such as modularity, abstraction, convention and configuration over customization, dependency management, maintainability, exception management, testing, instrumentation, SOLID, KISS, and DRY apply to composable solutions as they would to any other software. In fact, composable architecture evolved to address many of these concerns, which are well-documented elsewhere.

Maybe most importantly, composable architecture strongly encourages separation of concerns and lose coupling between systems and their components. In fact, this may be the main value of composable design, as well as one of its most significant challenges. Solutions that integrate products tightly can have short-term advantages such as simplicity and expediency but result in the same problems and limitations that resulted from previous generations of software architecture (“re-creating the monolith”).

Use SaaS Products

Whenever possible use SaaS software products. The advantages of SaaS, such as infrastructure abstraction, dynamic (scalable) resource allocation, scalability, redundancy, geographical dispersion, and otherwise, are well-documented elsewhere.

Most organizations should focus on their core business domain rather than developing expertise in software application infrastructure management. Where needed, such as in some cases for healthcare, finance, and other verticals, host SaaS offerings from vendors in your own private cloud. If you are spending significant time and money managing non-SaaS infrastructure, you might not be taking an optimal approach to composable architecture.

Do not fall victim to “Not Invented Here” syndrome. The more code you write, the more you will have to maintain, the more technical debt you will collect, and the greater your long-term cost of ownership will be. Take advantage of solutions already developed and tested by vendors focused on specific problem domains.

Vendor Selection

Choose composable software vendors and products that focus on a single problem domain, such as content management (CMS), search, Customer Relationship Management/Customer Data Platform (CRM/CDD), commerce (including individual subfunctions such as product information management, tax calculation, payment, delivery provider management, order management, order fulfillment, inventory, and so forth), Depending on too many features from a single vendor can lead to tight coupling, which could creases vendor lock-in. This can increase productivity in the short term but defeats the purpose of composable.

Expect Errors

Networks and networks will never be completely reliable. Expect all kinds of errors and, to the best of your ability, account for them in advance – in design as well as in code.

Consider Environments and Mocking in Advance

In general development and test instances of your solution should not access production applications. Especially in the early phases of development of a complex solution, test instances of supporting applications may not be available or accessible or may not contain data sufficient for testing. Even after a solution is in production, there are often cases where the development and test instances cannot or should not access test instances of applications.

Implement a solution for mocking Webservice APIs and accessing those mocks rather than the actual applications, as well as a solution to configure whether the application accesses mocks or actual applications. And, of course, instead of hardcoding details about systems, use configuration to control which systems to access.

Architect for Change

Change is inevitable. Design the solution with expectations that requirements will evolve, systems will come and go, and APIs and JSON formats will change. Insulate and abstract applications from implementation details.

Optimize the Architecture

Software developers can tend to pre-optimize: to focus on the performance around small details rather than the overall solution. With composable, it is important to optimize the architecture of the solution, which should involve relatively little code as compared to a traditional all-in-one application. For example, instead of focusing on the raw performance of an individual service, implement solutions that invoke services in parallel rather than sequentially whenever possible. In general, if you can invoke something asynchronously, do so.

Instrument

Implement instrumentation such as logging from the outset. This functionality can be useful in development but can be critical in production. Accounting for instrumentation late in the development process increases the effort required to achieve these objectives.

Aggregate and Normalize

Implement a software infrastructure layer that aggregates and normalizes data from multiple back-end systems before its delivery to your solutions.

Updates made 14.May.2024:

Balance Monolithic vs. Multiple Vendors

The more vendors in your stack, the more time spent researching product and negotiating pricing, the greater the complexity, the higher the amount of vendor-specific development knowledge to obtain, the larger the number of risks, the higher the difficulty of troubleshooting, the greater volume of custom integration code to implement, the more potential for finger pointing at difficult times, and likely, the higher the costs for licensing, implementation, and maintenance. Conversely, the fewer vendors, the tighter the coupling and the greater the vendor lock-in (which defeats some of the objectives of composable), the reduced potential for using the most suitable applications, and the increased difficulty of replacing a vendor (say, if they do not meet expectations, change their pricing, or outright fail). Walking this vendor selection razor may be the most challenging aspects of architecting and implementing composable solutions.

Validate Your Vendors

Don’t assume; confirm – before you purchase. How many staff? In what time zones? In what roles? Who are they? Who are the customers? How does the growth curve look? What is the annual recurring revenue?

Every application in your stack may become a single point of failure that can bring down an entire solution, where that solution may be a primary component in the infrastructure of the organization.

It’s relatively easy to market software. It’s relatively hard to deliver solutions. It’s comparatively easy to start an SaaS composable software company. It’s relatively hard to run one, especially at scale.

Test the Service Level Agreement

Give the critical support process a whirl – again, before you purchase. Don’t wait until your critical infrastructure depends on an application to find out that its vendor does not respond or address issues in real-time. Let the vendor know your support expectations.

Get the Source Code in Escrow

According to ChatGPT: “about 20% of small businesses fail within their first year, and roughly 50% fail within five years. About one-third survive 10 years or more…Many software startups face high failure rates. Research shows that around 90% of startups fail, with 21.5% failing in the first year, 30% in the second year, 50% by the fifth year, and 70% by the tenth year.” This is based on experiences before “AI” and harder economic times in the tech industry. I have serious reservations about what we currently refer to as “AI” (which is often really just algorithms that few people understand using large and largely uncontrolled data sets). In any case, this generation of “AI” may not be a true opportunity for most software vendors, especially those that don’t adapt and incorporate it quickly and correctly.

Composable solutions tend to become the lifeblood of an organization, and possibly the most significant software infrastructure of a company. If a vendor goes out of business, you may not have a great deal of time to replace their applications. Optimally, you can at least run the software on your own infrastructure even if you cannot maintain the source code. Hopefully, there can be a graceful transition.

Ensure Private Cloud Support

This is basically a corollary of the previous point. The source code won’t do much good if you can’t run it. Even if you need to quickly hire staff or engage consultants to manage the transition, you should ensure that you will not need to shut down your business for some time because a single vendor failed. You may even want test the process of moving that product to your own cloud.

Conduct a Proof of Concept or Minimum Viable Product Evaluation

Again, don’t make assumptions – confirm your expectations in advance of commitment.

Get Everything in Writing. *BEFORE* the Sale.

If the vendor won’t write something down, it probably isn’t true. Vendors are scared of being called out in public for deception, and even more terrified of potential lawsuits for fraud. If it gets to that point, you’ve already lost revenue and suing a bankrupt company won’t do anyone any good. I can tell you from experience: “when the lawyers get involved, only the lawyers win.” The point of getting things in writing as early as possible in the sales process is more to keep vendors honest than to provide evidence for an eventual court case.

Conclusion

Human knowledge and its application to software architecture are always evolving. A list like this will never be complete, and converse perspectives are valid.

Originally posted at:

One thought on “Best Practices in Composable Enterprise Solution Implementation

Leave a comment