9 hours ago โ€ข Milan Jovanoviฤ‡

I used this approach to optimize an API endpoint and make it 10x faster.

From ๐Ÿญ๐˜€ โžกโžกโžก ๐Ÿด๐Ÿฌ๐—บ๐˜€

So, what's this "magic" approach?

The endpoint was aggregating data from a few services. It sent several HTTP requests and then combined the results.

These requests did not depend on each other. Which means we could parallelize them and execute them asynchronously.

This leads to a massive performance improvement.

But there's a catch...

What happens if any of these requests fail?

This is where resilience comes in.

I wrote an in-depth guide on building resilient applications in .NET.

You can check it out here:  https://www.milanjovanovic.tech/blog/building-resilient-cloud-applications-with-dotnet/?utm_source=YouTube&utm_medium=social&utm_campaign=20.05.2024 

๐—ฃ.๐—ฆ. If you liked this, you will love The .NET Weekly newsletter. Join 49,000+ engineers to improve your .NET and software architecture skills.

Subscribe here โ†’  https://bit.ly/44BhYim 

16 hours ago โ€ข Milan Jovanoviฤ‡

Monoliths are simple to work with, and I appreciate this very much.

Especially when it comes to database handling transactions.

- Open a transaction
- Do some work
- Commit the changes

Walk in the park. Right?

However, this doesn't work in distributed systems because you can have many different databases involved.

So, your first idea could be to use a distributed transaction.

You can choose between:

- Two-Phase Commit (2PC)
- Saga (eventual consistency)

A two-phase commit gives you an atomic transaction, but it can also be a performance bottleneck. When a failure occurs, rolling back all the changes is expensive.

So, I prefer to use the Saga pattern with messaging.

It enables an application to maintain data consistency across many services without using 2PC

โœ… No deadlocks.
โœ… Highly scalable.

The downside is the programming model is more complex.

For example, I have to design compensating actions for each step.

Here's how you can implement Sagas with Rebus and RabbitMQ:  https://www.milanjovanovic.tech/blog/implementing-the-saga-pattern-with-rebus-and-rabbitmq?utm_source=YouTube&utm_medium=social&utm_campaign=20.05.2024 

---

๐—ฃ.๐—ฆ. If you liked this, you will love The .NET Weekly newsletter. Join 49,000+ engineers to improve your .NET and software architecture skills.

Subscribe here โ†’  https://bit.ly/44BhYim 

1 day ago โ€ข Milan Jovanoviฤ‡

You can use EF 8 raw SQL queries to execute updates on your database.

Worries about SQL injection attacks?

Don't worry. This isn't string interpolation.

The argument for this method is a FormattableString.

It will capture the interpolated values and convert them into SQL parameters.

This method will always execute parameterized queries unless you hardcode the values. However, if you decide to go that route, it's your responsibility.

ExecuteSql won't automatically start a transaction, but it can use the ambient transaction if you create it first. Keep that in mind.

EF 8 raw SQL queries give you a lot of new functionality.

For example, you can query unmapped types (something we couldn't do before).

Learn more here:  https://www.milanjovanovic.tech/blog/ef-core-raw-sql-queries?utm_source=YouTube&utm_medium=social&utm_campaign=20.05.2024 

---

๐—ฃ.๐—ฆ. If you liked this, you will love The .NET Weekly newsletter. Join 49,000+ engineers to improve your .NET and software architecture skills.

Subscribe here โ†’  https://bit.ly/44BhYim 

1 day ago โ€ข Milan Jovanoviฤ‡

๐—ง๐—ต๐—ฒ ๐——๐—ผ๐—บ๐—ฎ๐—ถ๐—ป ๐—น๐—ฎ๐˜†๐—ฒ๐—ฟ ๐—ณ๐—ผ๐—น๐—ฑ๐—ฒ๐—ฟ ๐˜€๐˜๐—ฟ๐˜‚๐—ฐ๐˜๐˜‚๐—ฟ๐—ฒ ๐˜€๐—ต๐—ผ๐˜‚๐—น๐—ฑ ๐—ฒ๐˜…๐—ฝ๐—ฟ๐—ฒ๐˜€๐˜€ ๐—ถ๐—ป๐˜๐—ฒ๐—ป๐˜.

This is one of the essential concepts of screaming architecture.

The Domain sits at the core of Clean Architecture.

It's where you define your entities and the most important business logic.

A few weeks ago, I was looking at a project I built many moons ago.

The folder structure in the Domain layer bothered me.

It was grouping classes by technical concerns instead of features.

The symptoms of this are folders like:

- Entities
- Enumerations
- Exceptions
- Repositories
- ValueObjects

I'm sure you've done (or seen) this at some point.

What's the problem with grouping by technical concerns?

This folder structure doesn't tell you anything about the Domain.

So, I reorganized the folders by grouping them by feature (or vertical slice).

When you do this, domain concepts start appearing in the folder structure.

The benefits of the new approach are:

- Better cohesion
- High coupling for a single feature
- Low coupling between unrelated features

If you've heard of Vertical Slice Architecture, this idea is similar.

๐—ฃ.๐—ฆ. If you liked this, you will love The .NET Weekly newsletter. Join 49,000+ engineers to improve your .NET and software architecture skills.

Subscribe here โ†’  https://bit.ly/44BhYim 

What do you think about this approach? 

2 days ago โ€ข Milan Jovanoviฤ‡

I recently read "Software Architecture with C# and .NET 8".

Here's why you should consider this book. ๐Ÿ‘‡

It starts from the fundamentals. When was the last time you read about the waterfall model in a book? Maybe we've been relying too much on Agile.

It also discusses Non-Functional Requirements and how they can impact your choice of software architecture.

You'll also read about best practices for coding in C#. Remember, simple code is good code. The authors discuss coupling, maintainability, cyclomatic complexity, etc.

Domain-driven design is an unavoidable topic in today's software development. This chapter focuses more on tactical patterns. The authors also touch on CQRS and Event sourcing.

Here are a few more topics that you'll read about:

- Service-oriented architecture
- Microservices architecture
- Serverless cloud functions
- SQL and NoSQL databases
- Kubernetes

Overall, I enjoyed this book, and I think you will, too.

You can grab your copy here:  https://amzn.to/43ctrEn 

---

๐—ฃ.๐—ฆ. If you liked this, you will love The .NET Weekly newsletter. Join 49,000+ engineers to improve your .NET and software architecture skills.

Subscribe here โ†’  https://bit.ly/44BhYim 

2 days ago โ€ข Milan Jovanoviฤ‡

Do you want to learn Domain-Driven Design?

Here are 21 free resources to fast-track your journey. ๐Ÿ”ฅ

1. What is an Entity -  https://youtu.be/00tCda35Bvk 

2. What is a Value Object -  https://youtu.be/P5CRea21R2E 

3. What is an Aggregate Root -  https://youtu.be/0D3EB2jvQ44 

4. Domain validation approaches -  https://youtu.be/KgfzM0QWHrQ 

5. Domain Events pattern -  https://youtu.be/BimfDeDV4yU 

6. The DDD Trilemma -  https://youtu.be/eC7GMGIR4Gw 

7. Repository pattern -  https://youtu.be/h4KIngWVpfU 

8. Specification pattern -  https://youtu.be/rdY5ElleWKY 

9. Unit of Work pattern -  https://youtu.be/vN_j1Bs0ALU 

10. Design a Rich Domain Model -  https://youtu.be/1Lcr2c3MVF4 

11. Smart Enums in C# -  https://youtu.be/v6cYTcEfZ8A 

12. Snapshot Pattern -  https://youtu.be/HhZ4DtON404 

13. Design a Rich Domain Model V2 -  https://youtu.be/fO2T5tRu3DE 

14. Strongly Typed IDs -  https://youtu.be/LdrMdIabE1o 

15. Fix Anemic Domain Model -  https://youtu.be/6gwIDiUk2h4 

16. Map DDD to Database -  https://youtu.be/IlXnIe6p_Uk 

17. Incomplete Aggregates? -  https://youtu.be/cCnZJE0wEjY 

18. Double Dispatch Pattern -  https://youtu.be/wi_wsw5Gp6Q 

19. Fix Broken Aggregates -  https://youtu.be/BY8DHD6LitU 

20. Organizing Domain Folders -  https://youtu.be/R-XODYF2iBQ 

21. DDD - Getting started -  https://youtu.be/q74saF54w8I 

Hope these are helpful.

Have an awesome day! 

---

P.S. Want to become a better software engineer? Each week, I send one piece of practical advice about .NET and software architecture. 

Join 49,000+ engineers:  https://bit.ly/44BhYim 

3 days ago โ€ข Milan Jovanoviฤ‡

It took me 6 years to become a software architect.

So, I'm sharing what I learned to help you get there faster.

Here's what I did on a high level:

- Master the fundamentals
- Master system design
- Improve my soft skills
- Earn the trust of others

I want to preface this post with a quote from a friend of mine:

"Software architecture is only a small part about the available tech choices, and much more about making and owning these decisions (for the good and the bad). "

With that said, let's break down the journey to becoming an architect.

๐— ๐—ฎ๐˜€๐˜๐—ฒ๐—ฟ ๐˜๐—ต๐—ฒ ๐—ณ๐˜‚๐—ป๐—ฑ๐—ฎ๐—บ๐—ฒ๐—ป๐˜๐—ฎ๐—น๐˜€

This is where I spent most of my time.

I'm also confident this is where most of you are in your journey.

In this stage, you want to master your technology stack of choice. You should be able to build a production-ready system from scratch.

You must understand the fundamental concepts of software engineering. Architectural styles, design patterns, cost analysis, tradeoffs, problem-solving, etc.

You have to work on production systems with real risks to develop these skills.

๐— ๐—ฎ๐˜€๐˜๐—ฒ๐—ฟ ๐˜€๐˜†๐˜€๐˜๐—ฒ๐—บ ๐—ฑ๐—ฒ๐˜€๐—ถ๐—ด๐—ป

So, you can write some code and set up a simple architecture?

That's great, but your application doesn't operate in a vacuum. Today's systems contain a database, message brokers, caches, observability systems, and more.

Your application will likely integrate with any number of third-party services.

You need to understand how all these components operate together.

- What is the purpose of each component in the system?
- How do they help you achieve the required qualities (-ilities)?

The systems we build have one purpose: solving business problems.

Always keep that in mind.

๐—œ๐—บ๐—ฝ๐—ฟ๐—ผ๐˜ƒ๐—ฒ ๐—บ๐˜† ๐˜€๐—ผ๐—ณ๐˜ ๐˜€๐—ธ๐—ถ๐—น๐—น๐˜€

Applying software architecture theory in practice requires talking with others.

You also have to own your decisions, for the good and the bad.

Learn to work with others, communicate effectively, and listen.

I'll write a separate post on improving soft skills, as there is much to say.

๐—˜๐—ฎ๐—ฟ๐—ป ๐˜๐—ต๐—ฒ ๐˜๐—ฟ๐˜‚๐˜€๐˜ ๐—ผ๐—ณ ๐—ผ๐˜๐—ต๐—ฒ๐—ฟ๐˜€

Why should anyone listen to you and what you have to say?

You're the person who can solve problems and follow through with solutions. You can go up and down the tech stack and to different levels of abstraction, allowing you to evolve the solution in light of new problems.

Can you get there in a few short years? Most likely not.

But that shouldn't deter you since nothing worth having comes easy.

This post is becoming too long already, and I still have many things to say.

We've only scratched the surface of what it means to be a software architect.

I'm considering converting this into a proper article and expanding on some ideas.

Hopefully, you got some value from my ramblings.

๐—ฃ.๐—ฆ. If you liked this, you will love The .NET Weekly newsletter. Join 49,000+ engineers to improve your .NET and software architecture skills.

Subscribe here โ†’  https://bit.ly/44BhYim 

What do you think you need to learn to become a software architect? 

3 days ago โ€ข Milan Jovanoviฤ‡

The Outbox pattern is a game changer. ๐Ÿ“ฆ

Here's everything you need to know about it.

The Outbox pattern provides a reliable way to publish messages in distributed systems.

Here's the gist of the Outbox pattern:

- You don't publish messages directly
- Instead, you store them in the database (Outbox)
- A worker service polls the database for new messages
- The worker service publishes each message asynchronously

Why would you want to do this?

Distributed systems are complex, and things break all the time.

A downstream service could be down, and the network may not be available. If you try multiple operations at runtime and one fails, the whole request fails. This also means your request isn't atomic (transactional).

The Outbox pattern helps you decouple your request from its side effects. If you work with an SQL database, your transaction is atomic. You can persist the messages in the Outbox table as part of a single transaction.

A background worker will process the messages later.

What's the price you have to pay?

Eventual consistency and dealing with message retries (publishing more than once).

On the consumer end, you still need to handle duplicates in case of retries.

This messaging semantic is called "at-least-once" delivery.

๐—ฃ.๐—ฆ. If you liked this, you will love The .NET Weekly newsletter. Join 49,000+ engineers to improve your .NET and software architecture skills.

Subscribe here โ†’  https://bit.ly/44BhYim 

Did you use the Outbox pattern before? 

4 days ago โ€ข Milan Jovanoviฤ‡

How can you build an in-memory message bus?

I'll show you a simple approach in .NET + an alternative using a popular library.

Messaging plays a crucial role in modern software architecture, enabling communication and coordination between loosely coupled components.

An in-memory message bus is particularly useful when high performance and low latency are critical requirements.

I have to preface this by saying that an in-memory message bus is far from a silver bullet.

There are many caveats to using it, as you will soon learn.

But first, let's start with the pros of using an in-memory message bus:

- Because it works in memory, you have a very low-latency messaging system
- You can implement asynchronous (non-blocking) communication between components

However, there are a few drawbacks to this approach:

- Potential for losing messages if the application process goes down
- It only works inside of a single process, so it's not useful in distributed systems

A practical use case for an in-memory message bus is when building a modular monolith.

You can implement communication between modules using integration events.

When you need to extract some modules into a separate service, you can replace the in-memory bus with a distributed one.

How can you implement an in-memory message bus?

One solution could be using .NET Channels.

Here's a step-by-step guide:  https://www.milanjovanovic.tech/blog/lightweight-in-memory-message-bus-using-dotnet-channels/?utm_source=YouTube&utm_medium=social&utm_campaign=13.05.2024 

---

If you liked this, consider joining 48,000+ engineers in The .NET Weekly.

โœ… One practical tip every Saturday
โœ… .NET best practices and actionable advice
โœ… Software Architecture deep dives and fresh ideas

Subscribe here โ†’  https://bit.ly/3Qx7Cu5 

4 days ago โ€ข Milan Jovanoviฤ‡

What is an API Gateway?

An API gateway is the "front door" to your backend services and APIs.

It acts as an intermediary layer, handling client requests and routing them to the appropriate destinations.

The key characteristics of an API gateway are:

- Request routing and composition
- Authentication and authorization
- Load balancing
- Rate limiting
- Monitoring
- Caching

An important role of API gateways is security.

You can implement authentication at the gateway level, and only authenticated requests can be proxied to the backend services.

A popular proxy library in .NET is YARP, which integrates with the built-in authentication and authorization components.

Here's how you can implement API gateway authentication in ASP .NET Core:  https://www.milanjovanovic.tech/blog/implementing-api-gateway-authentication-with-yarp/?utm_source=YouTube&utm_medium=social&utm_campaign=13.05.2024 

---

If you liked this, consider joining 48,000+ engineers in The .NET Weekly.

โœ… One practical tip every Saturday
โœ… .NET best practices and actionable advice
โœ… Software Architecture deep dives and fresh ideas

Subscribe here โ†’  https://bit.ly/3Qx7Cu5