Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Microservices Design Patterns in .NET

You're reading from   Microservices Design Patterns in .NET Making sense of microservices design and architecture using .NET Core

Arrow left icon
Product type Paperback
Published in Jan 2023
Publisher Packt
ISBN-13 9781804610305
Length 300 pages
Edition 1st Edition
Tools
Arrow right icon
Author (1):
Arrow left icon
Trevoir Williams Trevoir Williams
Author Profile Icon Trevoir Williams
Trevoir Williams
Arrow right icon
View More author details
Toc

Table of Contents (21) Chapters Close

Preface 1. Part 1: Understanding Microservices and Design Patterns
2. Chapter 1: Introduction to Microservices – the Big Picture FREE CHAPTER 3. Chapter 2: Working with the Aggregator Pattern 4. Chapter 3: Synchronous Communication between Microservices 5. Chapter 4: Asynchronous Communication between Microservices 6. Chapter 5: Working with the CQRS Pattern 7. Chapter 6: Applying Event Sourcing Patterns 8. Part 2: Database and Storage Design Patterns
9. Chapter 7: Handling Data for Each Microservice with the Database per Service Pattern 10. Chapter 8: Implement Transactions across Microservices Using the Saga Pattern 11. Part 3: Resiliency, Security, and Infrastructure Patterns
12. Chapter 9: Building Resilient Microservices 13. Chapter 10: Performing Health Checks on Your Services 14. Chapter 11: Implementing the API and BFF Gateway Patterns 15. Chapter 12: Securing Microservices with Bearer Tokens 16. Chapter 13: Microservice Container Hosting 17. Chapter 14: Implementing Centralized Logging for Microservices 18. Chapter 15: Wrapping It All Up 19. Index 20. Other Books You May Enjoy

A deep dive into microservices and its key elements

Traditionally, in software development, applications have developed as a single unit or monolith. All of the components are tightly coupled, and a change to one component threatens to have rippling effects throughout the code base and functionality. This makes long-term maintenance a major concern and can hinder developers from rolling out updates quickly.

Microservices will have you assess that monolith, break it into smaller and more perceivable applications. Each application will relate to a subsection of the larger project, which is a called domain. We will then develop and maintain the code base per application as independent units. Typically, microservices are developed as APIs and may or may not interact with each other to complete operations being carried by users through a unifying user interface. Typically, the microservice architecture comprises a suite of small independent services, which communicate via HTTP (REST APIs) or gRPC (Google Remote Procedure Call). The general notion is that each microservice is autonomous, has a limited scope, and aids in a collectively loosely coupled application.

Building a monolith

Let’s imagine that we need to build a health facility management web application. We need to manage customer information, book appointments, generate invoices, and deliver test results to customers. If we were to itemize all the steps needed to build such an application, key development and scoping activities would include the following:

  1. Model the application, and scope the requirements for our customer onboarding, user profiles, and basic documents.
  2. Scope the requirements surrounding the process of booking an appointment with a particular doctor. Doctors have schedules and specialties, so we have to present the booking slots accordingly.
  3. Create a process flow for when a match is found between a customer and a doctor. Once a match is found, we need to do the following:
    1. Book the doctor’s calendar slot
    2. Generate an invoice
    3. Potentially collect a payment for the visit
    4. Send email notifications to the customer, doctor, and other relevant personnel
  4. Model a database (probably relational) to store all this information.
  5. Create user interfaces for each screen that both customers and the medical staff will use.

All of this is developed as one application, with one frontend talking to one backend, one database, and one deployment environment. Additionally, we might throw in a few third-party API integrations for payment and email services. This can be load balanced and hosted across multiple servers to mitigate against downtime and increase responsiveness:

Figure 1.1 – Application building

Figure 1.1 – Application building

However, this monolithic architecture introduces a few challenges:

  • Attempts to extend functionality might have ripple effects through multiple modules and introduce new database and security needs.

Potential solution: Perform thorough unit and integration testing.

  • The development team runs the risk of becoming very dependent on a particular stack, making it more difficult to keep the code base modern.

Potential solution: Implement proper versioning strategies and increment them as the technology changes.

  • As the code base expands, it becomes more difficult to account for all of the moving parts.

Potential solution: Use clean architectural methods to keep the code base loosely coupled and modular.

The reality is that we can overcome some of these challenges with certain architectural decisions. This all-in-one architecture has been the de facto standard, and frankly, it works. This project architecture is simple, easy enough to scope and develop, and is supported by most, if not all, development stacks and databases. We have been building them for so long that perhaps we have become oblivious to the real challenges that prevail as we try to extend and maintain them in the long term.

Figure 1.2 shows the typical architecture of a monolithic application:

Figure 1.2 – One user interface is served by an API or code library with business logic and is serviced by one database

Figure 1.2 – One user interface is served by an API or code library with business logic and is serviced by one database

Now that we have explored the monolithic approach and its potential flaws, let us review a similar application built using microservices.

Building microservices

Now, let us take the same application and conceptualize how it could be architected using microservices. During the design phase, we seek to identify the specific functionalities for each tranche of the application. This is where we identify our domains and subdomains; then, we begin to scope standalone services for each. For example, one domain could be customer management. This service will solely handle the user account and demographic information. Additionally, we could scope bookings and appointments, document management, and finally, payments. This then brings another issue to the foreground: we have dependencies between these three subdomains when we need service independence instead. Using domain-driven design, we then scope out where there are dependencies and identify where we might need to duplicate certain entities. For instance, a customer needs representation in the booking and appointments database as well as payments. This duplication is required if we are using separate databases per service (which is strongly encouraged).

The microservices require us to properly scope the flow of operations that involve multiple services playing a part. For instance, when making a booking, we need to do the following:

  1. Retrieve the customer making the booking.
  2. Ensure that the preferred time slot is available.
  3. If available, generate an invoice.
  4. Collect the payment.
  5. Confirm the appointment.

That process alone has some back-and-forth processing between the services. Properly orchestrating these service conversations is very critical to having a seamless system and adequately replacing a monolithic approach. Therefore, we introduce various design patterns and approaches to implementing our code and infrastructure. Even though we break potentially complex operations and workflows into smaller and more perceivable chunks, we end up in the same position where the application needs to carry out a specific operation and carry out the original requirements as a whole.

Figure 1.3 shows the typical architecture of a microservices application:

Figure 1.3 – Each microservice is standalone and unifies in a single user interface for user interactions

Figure 1.3 – Each microservice is standalone and unifies in a single user interface for user interactions

Now that you are familiar with the differences between the monolithic and microservices approaches, we can explore the pros and cons of using the microservices design pattern.

You have been reading a chapter from
Microservices Design Patterns in .NET
Published in: Jan 2023
Publisher: Packt
ISBN-13: 9781804610305
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image