From the course: Advanced Azure Microservices with .NET for Developers
What we are going to build - Azure Tutorial
From the course: Advanced Azure Microservices with .NET for Developers
What we are going to build
- [Instructor] To get the most out of this training course, I've already created some code to speed up the learning experience and also be able to balance the course length. We have three microservice projects built with ASP.NET Core. These microservices are Rescue, Pet, and Hospital. The Pet microservice stores its data in a SQL Server database by using Entity Framework Core. In Chapter 1, we'll implement code to communicate between microservices in a loosely coupled fashion. For this, we'll use Azure Service Bus topics. The Pet microservice publishes event messages to Azure Service Bus that are asynchronously brokered to the Rescue and Hospital microservices. Just like the Pet microservice, both Rescue and Hospital use a SQL Server database and the Entity Framework Core to persist the incoming events data. In Chapter 2, the CQRS pattern will expand the current codebase to add some commands and value objects and will create a new RescueQuery microservice. In Chapter 3, Event Sourcing and Microservices, we're going to store the individual events of the Patient aggregate in Azure Cosmos DB. Then we're going to create a new Azure function that automatically obtains the created items. In other words, the Patient events. We're going to implement code to project the current state of the Patient entity to a SQL Server database. Additionally, we'll add a new PatientQuery controller that retrieves the projected data. In a microservices system, it'll be an ineffective for a client application to communicate to each service directly. That's why in Chapter 4, API Gateway, we'll build a new API Gateway service that could sit in the middle of the client applications and the rest of the microservices. Then we're going to add crosscutting concerns in the microservices such as versioning and centralized logging. Lastly, we're going to containerize all the microservices and use Docker Compose for running them as a group. There are countless ways of designing software, and actually there's not such thing as a perfect software architecture. Regardless, the code of this course follows some principles. The code implementation is inspired by domain-driven design principles and tools such as bounded context, aggregates, entities, value objects, and domain events. Also, the code implementation is pragmatic. That is, we're going to focus on the topics rather than on the details. For example, when handling commands, we're going to use an application service object directly in the controller. Also, we're going to implement queries and data access directly in the controller class. This leads me to the following principle. We're not going to overengineer the code. In real-world scenarios with microservices, sometimes it's okay not to follow some principles such as DRY. We'll try to avoid accidental complexity at all costs and avoid adding extra layers of indirection. We'll try to reduce the usage of third-party frameworks or libraries and opinionated frameworks. While there are many that we could use, I believe they could distract us from the things that really matter. Finally, one of our main goals will be to implement truly autonomous services. That's precisely one of the reasons for using microservices in the first place. Let's dive deeper into each microservice. The Pet microservice uses the Pet entity where all the domain logic is implemented. This microservice is able to receive commands to perform some actions and processes in the Pet domain model, and it also exposes a query. We can consider the Pet microservice as a core microservice in this course. This is because it publishes the required events for the other microservices to be useful. As I've already mentioned, it uses the Pet database that is a SQL Server database. The Rescue microservice uses the RescuedAnimal and Adopter entities. In addition, this microservice exposes some endpoints capable of receiving commands. Furthermore, it handles one of the integration events that the Pet microservice publishes. The database of this microservice is Rescue, and it's also a SQL Server database. The goal of the RescueQuery microservice is to expose an endpoint that returns data from the Rescue database. Both Rescue and RescueQuery microservices use the same database. Don't worry. This is okay when using the CQRS pattern. Again, pragmatism is the name of the game. The Hospital microservice uses the Patient aggregate that tracks all the domain events that happen. This is an essential trait of this aggregate since it'll be the basis for implementing the event sourcing pattern. Similar to the other microservices, Hospital receives commands, exposes a query, and handles an event. The event storage for this microservice is an Azure Cosmos DB database with a single container named Patients. The Hospital Projector function is triggered automatically by the Azure Cosmos DB change feed. This function rehydrates the state for a given patient and then it source the last state in the Hospital database in SQL Server. The PatientQuery endpoint uses this database as its data source. Lastly, our code will not handle transactions when purchasing data and triggering events. You can refer to the Transactional Outbox Pattern documentation if you want to do this. Deployment tasks are outside the scope of this course. However, they're often straightforward, particularly when using Docker Compose for your microservices. Finally, security topics such as authentication and authorization are also outside the scope of this course. Okay, that sums up what we're going to build. It's time to roll up our sleeves.