-
Notifications
You must be signed in to change notification settings - Fork 13
Microservice Sizing
| Main > Key Concepts > Microservice Sizing |
|---|
The term micro obviously does not mean the smaller the better. On the other hand, DDD bounded context is the most used criterion for defining the size of a microservice. But even what is a bounded context is open to discussion depending on who is modeling. Eventually it could lead to dozens of classes.
Hence Liquid prescribes two additional criteria so as to help define a good size for a microservice:
-
One controller class per microservice: let us consider that a published API resembling an OO view of the problem domain, that is, the microservice should be perceived as a domain aggregation - a complex entity class with properties and operations. Hence there should only be one controller class (or, better stating it, one facade class per each access method-and-protocol) exposing such aggregation functionality provide by the microservice. There are in the web plenty of examples of microservices with various controller classes, one for each aggregated entity. But that is usually due to the fact that only controllers are used for doing internal modularization.
-
One repository per microservice: on the other hand, a microservice should only persist one aggregated set of classes. Modern NoSQL databases offer this functionality naturally by storing serializations of such aggregations in JSON format. If a microservice demands data structures not feasible to be serialized and stored at once (in a single logical operation), this is a great sign of need for decomposition. So, one repository storing one aggregation model is a good criterion preventing microservices to quickly become "microliths" - as unfortunately happens when designers try to design microservices from classical relational data modeling techniques (and mindsets) instead of using non-relational ones.
Accordingly, Liquid promotes criterion (1) by considering controllers as just facades to several service, command and query classes encapsulating domain (business) logic.
And it promotes criterion (2) by giving each microservice one singleton instance of a preset repository such as the following:
Startup.cs
-------------------------------------------------------------------------------
WorkBench.UseRepository<CosmosDB>();
appsettings.json
-------------------------------------------------------------------------------
"CosmosDB": {
"Endpoint": "https://localhost:8081",
"AuthKey": "AUTHENTICATION_KEY",
"DatabaseId": "eShop",
"CollectionName": "Baskets" }
BasketService.cs
-------------------------------------------------------------------------------
var res = Repository.DeleteAsync(basketId);
If developers need to bypass these prescribed criteria, they can create as much controllers as they want - the same way they can do without Liquid.
If they need to work with multiple Liquid repositories, they can create separate (static) instances. The following example shows a CQRS microservice working with a different repository for performing write operations:
appsettings.json
-------------------------------------------------------------------------------
"CosmosDB_WRITE": {
"Endpoint": "https://localhost:8081",
"AuthKey": "AUTHENTICATION_KEY",
"DatabaseId": "eShop",
"CollectionName": "Baskets_W" }
SaveNewBasketHandler.cs
-------------------------------------------------------------------------------
static ILightRepository writeRepo = new CosmosDB("WRITE");
...
var res = writeRepo.AddOrUpdateAsync(basket);