A typical self-contained, often complex application that is generally deployed as a single unit is a monolithic application. As business requirements grow along with the needs of our users our applications become unwieldy. Microservice, a collection of many smaller services, hopes to alleviate monolithic pains through concise, single responsibility services that can be developed, tested, and deployed independently.
The bootstrapped developer's dilemma
One great benefit of microservices is the ability to deploy small pieces of the application independently, which in turn is also a burden for a budget-minded developer. Monolithic apps, while large, usually have the "luxury" of a code base deployed as a whole, to a single server (yeah yeah load balancing, etc).
Using Azure as an example for my side project www.perkbound.com which currently relies on 14 microservices means I must run 14 independent websites instances for the backend, and another instance for the frontend.
15 instances @ $54~/month, excluding SQL databases, instantly becomes unreasonably expensive which means I'm either back to a monolithic application or looking into Azure virtual machines meaning I lose all the benefits of the website instance and now don the operations hat managing patching, IIS, security, backup, and the list goes on.
I'm sure some of you are screaming at your monitor about Azure's service fabric and Amazon's containers, but being realistic we're still in a cost prohibitive environment.
So what is a "pseudo microservice"?
A "pseudo microservice", since I'm just making things up, is a monolithic application that forgoes the traditional multi-layered architecture in favor of encapsulated, internal microservices.
Alright... tell me more
In my quest to keep up on the buzziest words in web development my wallet grounded me. As junior of a mistake as it was, I enthusiastically refactored my monolithic app into 14 microservices assuming Azure had my back. When reality sunk in I had already fell in love with the simplicity microservices had brought to my application's architecture.
I begrudgingly moved the services back into my main solution, but I left each service in its own project, segregated from the rest of the application, still handling and internalizing its stores and data access. My previous, and the typical multi-layered monolithic application looked something like Fig 1.
Each service, due to its assembly location, could call any other service and instantiate any repository (and did, because I'm human). I could only contain functionality by being vigilant and ended up feature creeping myself into a rat's nest of accidental references.
Moving to the hybrid
With my microservices now moved back into my monolithic app I now have a structure that looks like Fig 2.
Functionality remains the same as it did in the initial monolithic app except now everything is compartmentalized. Service classes marshal requests to providers that perform the service's business logic. Commands/queries (repositories in this example) are 100% internal, if I want to interact with them in my app I must go through the service classes. Within each project I can (and don't) handle mappings anyway I please and use any ORM I please without distrupting the flow of the application.
I've gained some of the design benefits of microservice and combined them with the cost savings benefit of a monolithic single server deployment, oh joy!
A little nugety goodness
One of the side effects of moving to microservices initially was needing to reuse some of my "core" and "data" layer helper classes such as mappings, dapper context, unit of work, etc. To DRY this up I created a local nuget feed and put each of these components into their own packages to reference in each project.
When I moved my microservices back into my main solution I decided to stick with my nuget packages leaving me with a simpler code base to work with. Overall this has been a great move for the simplification of my code base.
I really enjoy developing microservices. The benefits of reduced complexity, single responsibility, focused testing, and single service deployments make microservices a pleasure to work with. While monolithic applications aren't going anywhere anytime soon it doesn't mean we can't benefit from some of the microservice design in our single site deployments.