NET-Microservices-Architecture-for-Containerized-NET-Applications-(Microsoft-eBook)
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
application. This approach provides a way to easily write a query that combines data from multiple<br />
tables.<br />
However, data access becomes much more complex when you move to a microservices architecture.<br />
But even when ACID transactions can or should be used within a microservice or Bounded Context,<br />
the data owned by each microservice is private to that microservice and can only be accessed via its<br />
microservice API. Encapsulating the data ensures that the microservices are loosely coupled and can<br />
evolve independently of one another. If multiple services were accessing the same data, schema<br />
updates would require coordinated updates to all the services. This would break the microservice<br />
lifecycle autonomy. But distributed data structures mean that you cannot make a single ACID<br />
transaction across microservices. This in turn means you must use eventual consistency when a<br />
business process spans multiple microservices. This is much harder to implement than simple SQL<br />
joins, because you can’t create integrity constraints or use distributed transactions between separate<br />
databases, as we’ll explain later on. Similarly, many other relational database features are not available<br />
across multiple microservices.<br />
Going even further, different microservices often use different kinds of databases. Modern<br />
applications store and process diverse kinds of data, and a relational database is not always the best<br />
choice. For some use cases, a NoSQL database such as Azure DocumentDB or MongoDB might have a<br />
more convenient data model and offer better per<strong>for</strong>mance and scalability than a SQL database like<br />
SQL Server or Azure SQL Database. In other cases, a relational database is still the best approach.<br />
There<strong>for</strong>e, microservices-based applications often use a mixture of SQL and NoSQL databases, which<br />
is sometimes called the polyglot persistence approach.<br />
A partitioned, polyglot-persistent architecture <strong>for</strong> data storage has many benefits. These include<br />
loosely coupled services and better per<strong>for</strong>mance, scalability, costs, and manageability. However, it can<br />
introduce some distributed data management challenges, as we will explain in “Identifying domainmodel<br />
boundaries” later in this chapter.<br />
The relationship between microservices and the Bounded Context<br />
pattern<br />
The concept of microservice derives from the Bounded Context (BC) pattern in domain-driven design<br />
(DDD). DDD deals with large models by dividing them into multiple BCs and being explicit about their<br />
boundaries. Each BC must have its own model and database; likewise, each microservice owns its related<br />
data. In addition, each BC usually has its own ubiquitous language to help communication between<br />
software developers and domain experts.<br />
Those terms (mainly domain entities) in the ubiquitous language can have different names in different<br />
Bounded Contexts, even when different domain entities share the same identity (that is, the unique ID<br />
that is used to read the entity from storage). For instance, in a user-profile Bounded Context, the User<br />
domain entity might share identity with the Buyer domain entity in the ordering Bounded Context.<br />
A microservice is there<strong>for</strong>e like a Bounded Context, but it also specifies that it is a distributed service.<br />
It is built as a separate process <strong>for</strong> each Bounded Context, and it must use the distributed protocols<br />
noted earlier, like HTTP/HTTPS, WebSockets, or AMQP. The Bounded Context pattern, however, does<br />
not specify whether the Bounded Context is a distributed service or if it is simply a logical boundary<br />
(such as a generic subsystem) within a monolithic-deployment application.<br />
30 Architecting Container- and Microservice-Based <strong>Applications</strong>