In "Modernize Your .NET Software Development Environment," I walked through some of my personal experiences with .NET-based n-tier architectures, touching on some pain points for enterprises that want to balance project costs with benefits received. I mentioned a couple of HTTP-based Microsoft technologies—Web API and SignalR—that set the stage for continuing our discussion about how to achieve an enterprise-grade architecture that will stand the test of time.
The project team's expertise was in using .NET technologies, so we chose to build a back end using Entity Framework, Windows Communication Foundation (WCF), and finally Web API to power our front end. Figure 1 is a simplified architecture diagram of various applications interacting with WCF. The orange color represents business logic.
Ideally, all business logic should be implemented in the domain layer. However, business logic often ends up creeping into your API layer. ASP.NET MVC makes this especially difficult, as I discussed in detail in "MVVM and .NET: A Great Combo for Web Application Development."
In this architecture our new application would be the Domain 3 app. A RESTful Web API helped us build a business-logic–free API, so we assumed we could do the same for our new WCF services. However, every application in this architecture was interdependent, because the WCF endpoints were concretely defined. Any change to an API would lead to recompilation of all three applications.
We wanted to use all the existing code to the maximum extent possible; however, we wanted to achieve this goal without sacrificing the quality of our new code. We needed to get rid of the interdependencies between our applications before we could meaningfully reform our architecture.
BizTalk is a great tool for reliable message delivery between discrete systems. In addition, BizTalk can be used to level the technological playing field, allowing systems of varying technological age to interact with one another. We decided to add BizTalk and a legacy mainframe system to our architecture, as Figure 2 shows.
In Figure 2 you can see that we removed the interdependencies between our applications. In the organization for which we were building this new application, everyone working with BizTalk had been accustomed to interfacing with it using a WCF service. Therefore, our brand-new project would need two entry points to the application logic. This meant doubling up on input validations, auditing, logging, authentication, and authorization. For an application dealing with dozens of entities, that's a considerable amount of overhead. Even worse, the slightest change to the API during development would include long turnaround times that required BizTalk project changes, compilations, and deployments—which vastly complicated what should have been a simple task.
In "Modernize Your .NET Software Development Environment," I mentioned that agile projects succeed over two times more often than their waterfall counterparts. Many enterprises attempt to execute agile projects; however, many enterprise development projects suffer from needlessly complicated architectures and a lack of focus. It's easy to abuse agile—and when you execute an agile methodology incorrectly, your project is almost guaranteed to fail.
One of the most important aspects of the Scrum methodology is its emphasis on focus. Teams focus on a select group of stories per sprint. On a daily basis, team members focus on one or two stories with the goal of completing a story without beginning another one, continuously iterating and incrementally delivering.
Applying the same principles to software architecture makes a lot of sense. When there are various entry points to an application, we increase the surface area that we must cover. This approach increases the potential for bugs, making the application more difficult to maintain and stretching our resources and mindshare thin.
I recently read an excellent book, Insanely Simple: The Obsession That Drives Apple's Success, by Ken Segall. I was pleasantly surprised to learn how Apple's marketing and design sensibilities can be applied to every aspect of software development. The following quote from Steve Jobs in particular highlights the importance of simplicity.
"When you first start off trying to solve a problem, the first solutions you come up with are very complex, and most people stop there. But if you keep going, and live with the problem and peel more layers of the onion off, you can oftentimes arrive at some very elegant and simple solutions."—Steve Jobs, Newsweek, 2006
Simple, but not too simple. Focus + Simple is a new mantra I adopted within the past year or so, which eventually led me to the realization that the simplest and most elegant enterprise architecture solution is one that employs only one API. HTTP REST makes this possible because it's compatible with emerging mobile technologies and existing back-end technologies.
To borrow another phrase from Steve Jobs, we must "think different" to simplify our architecture. From the beginning, I knew that having just one API would make our application a lot simpler. More importantly, our team didn't have the resources to build duplicates of our Web APIs in WCF.
Enterprise development can sometimes be more about politics than technology. So I communicated my "radical" idea over several weeks, slowly garnering everyone's support for the overall idea as I touted its benefits. My team got the green light to try using REST not only for browser communications but also for server-to-server communications.
However, we quickly hit a roadblock with our experiment: Pre-2013 versions of BizTalk don't support REST and JSON. To work around the issue, we worked with the BizTalk team to write a custom endpoint in C# that would enable REST and JSON support in BizTalk. Voila! We suddenly had messages coming in from a 25-year-old mainframe and other WCF services directly to our REST API. We were able to adequately encapsulate the complexities of a custom endpoint in BizTalk, making the overall architecture simpler. BizTalk 2013 makes this process even simpler because of its native support for REST and JSON.
Notice the deceptively subtle change in the architecture, as Figure 3 shows.
I can't understate the profound effect this change had on our development team for a period of 11 months. As a direct result of the efficiencies gained, we were able to focus our energy on delivering a richer user experience and more sophisticated authorization capabilities than previously planned. Auditing, authentication, and input validation features were very straightforward to implement, because of our consistent API layer.
In my next article, I'll dive deeper into the technical aspects of using ASP.NET Web API 2.1 to achieve a straightforward and scalable API. I'm publishing an open-source GitHub project to use as a concrete example. I'll be contributing to it as my examples become more elaborate—but feel free to take a sneak peek at my "One Api" Example Project for .NET Back-end Enterprise Projects, Mobile, & Web Clients.