Microservices: 3 slips into over-engineering and 1 into under-engineering

In this article I make a case for simplicity when designing a microservice based architecture. When done right they yield valuable advantages
such as autonomy and flexibility, but are paired with over-the-wire latency and deployment/hosting costs. This is not an advanced guided, but rather I want to help you question if you really need X approach, does it make to have a new process spin for it, can you have a glimpse of the hidden costs.

The links towards different technologies are not part of any sponsorship deal.

Mapper services

Personally, I find this case awkward.

You might come to this decision when service A needs to call service B. But of course, you need to map the DTO from domain A to what input B expects. In an overzealous love for microservice and attempt of decoupling the two, you create service C. It receives some data as JSON and returns a slightly rearrangement of it. No more information.

But by this logic, now you could consider to have 3 systems coupled. The case described is actually a DTO to DTO mapping, which belongs inside a process. Else, one could make the absurd case of needing to implement a mapper from A to C. Unless C doesn’t add data on the entity, (details, relation to other entities) C does not justify its existence. A service should return data it owns.

In the same manner, would you make a service to sort you an array of numbers it gets as input?

Wrapper services over static content

Not everything needs building a microservice for. When you have website resources such as scripts, style sheets, or images, one way is to serve them from the main server, and the other is from a CDN.

On the backend side, if you read some simple string values at initialization phase in a service, values that will change once every few month, even every few days, consider a cold storage and maybe polling, see S3 or BlobStorage. Care about authorized access? Research how you could restrict access based on IP or domain.
Hence, think really hard if you need a microservice for such content, in which you would pour maintenance and hosting costs.

Note The persistence store has to be distributed and scalable. The data needs to be at key-value pair level of simplicity from you applications point of view. Otherwise you end up in the “hitting same database” situation presented at the last point.

App specific configuration hosted by a remote service

Number of threads in some pool? Retry policies? Local in-memory cache durations? Does it make sense to have it in a far away service? There are chances that some values can reside pretty well in a settings file or as environment variables, so try this first. When proven otherwise, explore some already existing tools for configuration such as Consul, and save on that expensive development costs.

Hitting the same database from several microservices

Now this is the case when you had kept things too simple. It won’t take long until the database server will run out of connections, space, or computing power. Depending on the permissions each microservice has, an ugly scenario would be that it deletes objects such as tables that are used by another process. Also consider that if two such clients happen to read from the same table, and the schema has to change for one of them then you have to modify or at least adapt the second client for it to continue working. Sounds like a distributed monolith to me.

Doing so almost refutes the whole philosophy of microservice architecture. They should be independent and self-contained. They should own their data and have complete freedom on how it is persisted. They are abstractions that help de-couple processes. Obviously, they come with a fair amount of overhead for this flexibility. Yet, flexibility is what you should aim for.

Microservices should communicate via their explicitly exposed APIs. Over HTTP you can choose from ReST, GraphQL, gRPC or you may pick from the message queue implementations such as RabbitMQ, ApacheKafka.

Conclusion

Whilst, hopefully, most of you are well aware of the points above, others might be guilty of those slips. Maybe some would have been if not for this post. In any case, making mistakes especially in the somewhat novel and shape-shifting world of microservice is something we should expect and learn from. Hey, it could be me that’s still not getting it. Thanks for reading!