Please, enough about clean microservices architecture
A small disclaimer.
I am an active senior golang developer. In this regard, I can say that this opinion is completely indisputable. Your objective opinion does not exist, only a subjective one exists, because you and I are not stones. A stone is an object, a person is a subject. Can a subject give birth to something objective? But oh well, I got carried away.
Departure point number one
When I was a newbie, I built a terrible pipeline of “clean” microservices. At that moment, I realized that things would not go on like this. I started to study what kind of monster this “clean architecture” is. I read several famous books. But then I got my first job. And so I came and heard that they have the cleanest services in the world. I looked with wide eyes at such folders as “internal”, “pkg”, “storage”, “api”, where there are always “entity” files with interfaces, “const” with constants and then optionally, databases, protocols…
Then, as a true junior, I took it all on faith. And now I'm changing jobs. And there they do services differently. We have the best template in the world, follow it. The gRPC folder is now in the root, not in the api/gRPC folder, so that it can be imported. The database is now “repo”, constants are now in entity, and interfaces are where they are used.
I already started suspecting something back then, until I was amazed by the “SUPER MEGA CLEAN” service in the next company. Big. Complex. Confusing. Monoliths… Which by the way are microservices. I had to figure out for a month how everything works and where it is. Huge nesting, some dto, duplicate models for each action… I'm waiting for comments that I'm still a junior, since I couldn't figure it out.
The only thing that always remains the same is cmd/main. Thanks for that too.
Departure point number two
What do I want to say? I understand that your service is the best, that it was developed by a whole corporation of Indians to your order, but it turns out that this happens in every company. I'm not saying that let's adopt one standard, it's impossible. And I'm not saying that we should identify some approaches, they either exist or will appear on their own. I want to say that maybe we shouldn't kick newcomers and prove to colleagues with a sea at their mouths that they can go to a crypto startup with their approach?
I am generally always for sticking to the code style that is in the company, so I do not defend newbies or such toxic people. You come to a new company, there is an established code style and its own rules. Ideally, there should be a template with a description, and so-called “best practices” in the knowledge base.
Departure point number three
The amount of material written on this topic, various pictures, etc., makes me feel disgusted. Everywhere they write with different differences, which I will do too. This is strictly for beginners who want to “knock out” something similar to the truth. And then, once you get settled, look at other services and adhere to the rules that originated in the company.
Microservice example
Below I will give an example and describe each component.
At the root we have three folders:
cmd and in it right away main.go – the only thing that every company has. This is our entry point into the application. Here everything is initialized and launched
internal – a folder with internal modules. Here we put different api, db, and so-called “business logic”
pkg – packages that can be easily transferred to another service. For example, a client for communicating with a third-party service. Or a package for sending messages to Kafka.
There are also other files:
env – here are the variables for launching
gitignore – here we throw in what should not fly into the repository
gitlab-ci – purely because many companies now use gitlab
taskfile is a very handy thing, go google it
Now let's go in order – pkg. Here we add what I can copy and paste into another project. Different clients for sending requests mainly.
Internal folder. There are usually four folders here:
api – here we have our methods that the service will have. A regular router and handler with handlers. Here is everything that is related to the server.
config – a structure with nested structures. These are our configurators. We create the main structure “Config”, and in it nested structures for databases, servers, just variables that we need. It is loaded in the main and transferred to the corresponding structures.
repo – here we create a tight connection with our database. different methods that provide CRUD
service – a structure with methods for business logic.
General principles – we write both constants and interfaces in the entity. Also, in the folders where it is needed – we generate mocks. Structures are not exported everywhere (with small letters). We embed interfaces and communicate through them.
Bottom line
If you are a beginner, then all of the above should be enough for you. And if you are an experienced specialist, then I am glad that you spent time on this article. Be kinder to beginners, and beginners be more flexible, every company has its own rules and customs, your vision of clean code and a properly built microservice is needed only in a startup where you will be the first developer.
This is what kam1dere says.
Subscribe to my tgk
I also provide mentoring services.