Conversational Tech, Domain-Driven Design, and Microservices
See what a partnership of microservices and DDD looks like in the context of a conversational app.
Join the DZone community and get the full member experience.Join For Free
The advent of social media, financial technology, and the digital economy as a whole is fueled by hyper-advancement in technology — we know this already, it's a cliche, but the catch is that today's tech is becoming (and increasingly feels) more and more human. You can see more of this human-like advancement of tech in advanced AI systems like Sophia and Atlas of Boston Dynamics. While these are extreme examples, the common tech around us that has a direct point of contact to our day-to-day activities is becoming more conversational — from instant messaging to chatbots to IoT and personal assistants like Siri and Amazon Echo.
Until the realization of mainstream humanoid AI, the big guy in the spectrum of conversational tech is social media and instant messaging platforms, with 2.7 billion people on at least one of these platforms (which is roughly 75% of people with access to the Internet). This number is estimated to grow to 3.8 billion in 2021 and will represent about 50% of the world population.
The magnitude to which conversational tech has influenced our lives and habits cannot be emphasized enough. Research shows that an average smartphone user spends about 5 hours a day on their phones, with 90% of this time spent on social/messaging apps. It doesn’t take a genius to deduce that the bulk of our life has become the other end of a social trigger tube, digitally conversational and increasingly habitual. The reach of the #MeToo movement and the Cambridge Analytica episode give even more insight into how conversational tech is now deeply rooted across a vast definition of who we are and what triggers us and also serves as a channel for instant gratification.
Choosing financial technology as a focus area, conversational tech is still playing catch-up, but it is the future. More and more financial conversations are happening on these platforms (as with other focus areas); they are started there, but completed elsewhere. It's easy to say “Hey Bob, I’m sending you $20 for yesterday’s dinner, right?” then suspend the conversation to complete the transaction on Zelle or any other mobile banking app you have. It’d be interesting to complete that transaction within the context of the current conversation… Bob replies “Yes” and the money automatically leaves your bank account to his, with no additional clicks or instructions. Or, imagine using a financial assistant like Finie to complete that transaction.
It is clear that the future of financial services will be conversational and will appeal to a growing population of digital natives. These services will meet customers where they spend the most time, piping directly into their habits — this is why we built mTransfers.
mTransfers, a banking app that leverages your phone keyboard to provide financial services within the context of social media conversations, was first built without a dedicated backend, riding solely on the core APIs of the financial institution. The major consideration for this model starting out was both as a market entry play and privacy — the FIs were not immediately willing to give third-party access to transactional data even though that data was an independent entity separate from the hoard.
Following the need for scale and after following some FI guidelines, it was time to put together a backend infrastructure for mTransfers. The result was Drax, a containerized microservice-based system. Designing Drax prompted thoughts about hard boundaries and the marriage between Domain-Driven Design and microservices.
In its basic form, at first glance, this is what Drax looks like:
This is a focus on the design thinking of microservices using Drax as a case in point. A deeper dive into the Drax architecture itself, technical considerations, tools, failure mitigation, and more will come in a different article.
Domain-Driven Design and Microservices
The dawn of the 1970s ushered in mainstream support and usage of the Object Oriented Programming paradigm, which basically preaches that software components be modeled after real-life objects, having characteristics and behaviors that can only be manipulated by the object itself and can communicate with other objects through well-defined interfaces/messages. A dog (object) can walk (behavior) with her legs (characteristics) whenever she wants, but a human cannot make her walk without some form of well-defined message like going for a walk, or offering a snack, or throwing a ball — you get it; OOP introduces independent entities modeled as objects with bounded contexts in the form of abstractions and interfaces as a communication protocol.
Domain-Driven Design is not a design pattern, it is a set of guidelines and procedures that help us make design decisions based on business realities, and just like me, your first pinch of Domain-Driven Design might blur the lines of Object-Oriented Analysis and Design, (OOAD) but they are different in more ways than one. I like to think that while OOP implements domain specificity on a component/atomic level, DDD extends OOP by aggregating object models based on business logic.
Thinking in terms of DDD while designing microservices will help you avoid ending up with a “good” monolith. It is very easy to badly design a microservice-based system (if DDD is not fully understood) by separating concerns based on code modularity and Object Oriented Principles with “interprocess” communications in the form of function calls instead of “interservice” communication. For example, when you find yourself heavily using dependency injection for services, you are working on a modular monolith.
Take a payment gateway system, for example. If the Merchant service is a dependency of the Payment Transaction Service and the Payment Transaction Service is a dependency of the Settlement service, you are building a tightly coupled monolith — even with OOP principles. DDD helps us understand how to avoid tight coupling in microservices and safeguards Service Oriented Architecture in general.
In the Drax design above, we can have technical teams around each bank with a separate release cycle, version control, continuous integration, etc. As new banks come on board, all that needs to be done is wrap the Core Banking API according to the unified API interface definition, build the Docker image, add a service route/port to the Application Gateway or container manager like Kubernetes, and deploy. The Drax unified API definition specifies the expected requests and response models for its services and is documented using Swagger. With this, we do not need to change payload or add a routing code to the Application Gateway layer whenever a service is deployed. With this architecture, Drax significantly cut down integration time to a maximum of three days.
Take a look at this design:
This is a failed attempt at DDD. The boundaries are based on logical features and what should be defined as actions and messages. This will evidently lead to a pile of mud. First, these “domains” do not know what bank will be their vehicle so the mode of communication to the banks will be through a publish and subscribe model, introducing another complexity and a possible point of failure. Second, each bank has a different understanding and implementation of each feature, so it will be difficult to complete a transaction based only on messages and parameters, causing entities to be shared or unnecessarily duplicated across services. Third, that layer is just plain useless. Such segregation should happen on an implementation/component-based level using OOP principles.
This depiction is not near the entirety of what DDD entails nor close enough to the perfect microservice architecture, and we continue to make improvements, but this is a bid to encourage hard boundaries in a microservice-based system.
Published at DZone with permission of Maxwell Obi. See the original article here.
Opinions expressed by DZone contributors are their own.