Solution
Kloia and N11 team began a journey that combined the expertise on both sides to modernise their architecture. Kloia team had the expertise on Microservices and N11 on the domain. The initial phase was to agree on the conventions which are followed by the architectural sessions like:
-
Domains and Bounded-Contexts
-
Strong-consistency requirements
-
Event-Driven vs Event-Sourcing/CQRS use-cases
-
Underlying Platform Requirements
Based on those sessions, we decided to develop an internal Microservices framework which would make the developer experience easier. This framework would leverage the utilisation of software frameworks/libraries like Spring, Netflix and tools/systems like SQL, NoSQL, EventBus to be developer-friendly.
The framework offers the following:
-REST and Data Retrieval/Aggregation, which ensures the REST services are complying with maturity level 3.
-Stateless authentication/authorisation
-Decoupled Cache Management including distinct policies on separate entities for caching and the ability to be edited independently like:
- CacheKey
- JSON Contract
- Eviction & Index policy
- Circuit Breaker
-Automated Auditing is done automatically by the framework.
-API/Swagger Documentation should be generated automatically.
-Structured Logging, where logs are <missing verb> as JSON objects and are persisted on Elastic objects. Developer experience is one-line logging and the framework takes care of the transformations.
-Microservices Exception Handling, where the framework should be capable of returning the exception to the initial microservice who initiated the chain. Rather than having TRY-CATCH-THROW in each service, the framework handles the exception handling.
-Centralized Configuration is needed because Spring keeps the configuration of different environments in one file. The framework is capable of keeping those in separate files/folders.
-Resource Discovery/Registry is needed because each service may have more than one endpoint and more than one resource. On the top of Service Discovery which is already provided by Kubernetes, Framework is capable of keeping the Registry.
-Automated Dependency Registration, where extra fields are provided to Sprint Actuator health check: Dependencies-Data Sources(Couchbase,...)
Central Config service gathers the dependencies from each service. This standardises the library level dependencies and also encapsulates access to the data sources.
Those non-functional principles define the framework capabilities where several industry best practices are also used, such as Feign Client.
The further challenge in decoupling is Event-Driven vs. Event-Sourcing approach. We believe that every business has weak-consistency requirements. But this does not reflect the current software development approach, as we see strong-consistency everywhere, even though it is not needed.
We worked with N11 Software Teams to shift from the Monolith to Event Sourcing mindset. We utilized our open-source splitet to overcome the challenges like snapshots, rollbacks which also helped the cultural shift from Monolith to EventSourcing.