Over the last few years, our industry has moved away from monolith architectures to microservice architectures. For a good number of reasons, this trend continues to remain strong. One issue you may encounter with creating microservices if you are not using a monorepo is that you may have to build a new project whenever you need to add a new microservice to your app ecosystem. Creating a new project may include creating new repositories in Bitbucket/Github, configuring a continuous integration pipeline, adding build/deploy scripts, building the project based on some folder structure that has been determined by the team. It can also involve configuring how the service captures logs, communicating with other services, exposing an Open API definition, configuring a docker file, having a helm chart to deploy to k8s, installing external packages, and so on.
In other words, building a new project is hard enough, having to rebuild it over and over again as you add new microservices can be a painful experience that takes away time that can be better spent on something more useful. A solution to this problem is to create a microservice generator.
A microservice generator is a tool or combination of tools that create a microservice. They can accept configurations via parameter or can be preconfigured with some setting i.e arm vs x86. The goal of a microservice generator is to minimize the pain and time it takes to create a new project and at a minimum should be able to run on your local development environment with no additional work. Now, saying microservice generator may sound fancy, in reality, you could already have a microservice generator, the generator can be as simple as a bash or PowerShell script that creates a new code project and add all the required dependency needed to run the code.
If you’ve used Go or a service built with Go, like Helm, then you may already be familiar with the concepts of templates engines. If not, then all you really need to know is that template engines are used to interpolate strings effectively. In the dotnet world, we have the dotnet template engine. In fact, you may have already been enjoying its benefits without noticing it. Have you ever created a new dotnet console from the command line using the following syntax?
dotnet new console
In the command above, the console is one of the default templates that come with the .NET SDK. In dotnet you can create and publish your own templates, which is what I have used to create a microservice generator. Using the dotnet template engine as a microservice generator has in my opinion been super useful. The dotnet template engine has allowed me to create a microservice generator that can generate up a new dotnet project configured with a set number NuGet packages that I have determined to be essential i.e. Serilog, EF Core, XUnit. The template engine has also helped me ensure that logging is configured and ready for use, a developer doesn’t need to understand how the logs are extracted and propagated across our monitoring system, instead they just need to write what they would like to log. The template engine can be used to ensure a certain folder structure is followed. I’m a fan of structure proposed by Ardalis in Clean Architecture. The template engine can also be used to create and or modify a Docker file to ensure you can create a Docker image of your project as soon as you create the microservice.
See the greatest feature of the dotnet template engine in my opinion is that it works on any text file. This means you can use the engine to configure script files, Docker files, helm charts, configuration as code tools that are file-based, continuous integration tools like bitbucket pipeline, or any other continuous integration tool that are configured via a file, vscode configuration files like task.json, and so on. This reduces the amount of time a team has to spend on creating new projects. Imagine being able to create a new code project in less than five seconds that can be used and be deployed immediately, that has Unit Test projects with all the dependent libraries used for mocking and testing. That has been configured to use Docker and Helm. A project that has a continuous integration pipeline ready to be used. All from a single command execution. That is the power obtained by using the dotnet template engine. Hard to beat those benefits.
In a future blog post, I will demonstrate how to create, publish and consume your own microservice generator using the dotnet template engine.