Mastering ASP.NET Core with Minimal APIs & CQRS — Part 02: Project Setup with Vertical Slices

Sasanga Edirisinghe
5 min readDec 31, 2024

GitHub repo: https://github.com/SasangaME/MinimalApiDemo/tree/feature/project-structure

In our previous post, we introduced the concepts of ASP.NET Core Minimal APIs and the Command Query Responsibility Segregation (CQRS) pattern. Now, let’s enhance our understanding by developing a practical project that integrates these technologies.

Creating a New Project

Let’s create a new project with Visual Studio 2022 and select ASP.NET Core Web API template.

Then name the project in the next window and give a project location.

Select .NET 9.0: Ensure that .NET 9.0 is chosen as the target framework to leverage the latest features and improvements in your application.

Choose “None” for the authentication type, indicating that the project will not include built-in authentication mechanisms. We will create authentication and authorization from scratch in a later post.

  • Configure for HTTPS: Check this box to enable HTTPS, ensuring secure communication by default.
  • Enable OpenAPI Support: Select this option to include OpenAPI (formerly Swagger) support, which provides interactive API documentation and testing capabilities.
  • Use Controllers (uncheck to use minimal APIs): Uncheck this to utilize minimal APIs for a more streamlined approach, as we are not using controllers in this project.

Finally, click create button.

Here, we are going to use Vertical Slice Architecture in our project instead of using the traditional layered architecture.

Vertical Slice Architecture

Vertical Slice Architecture (VSA) is a software design approach that structures an application by features or use cases, rather than by technical layers such as presentation, business logic, and data access. Each “vertical slice” encompasses all the necessary components — from the user interface to the database — to implement a specific functionality. This method contrasts with traditional layered architectures, where similar types of code are grouped together, often leading to scattered implementations of individual features across multiple layers.

Key Principles of Vertical Slice Architecture:

  • Feature-Centric Organization: Code is organized around specific features or use cases, ensuring that all elements required for a feature are located together.
  • High Cohesion and Low Coupling: By encapsulating all aspects of a feature within a single slice, VSA promotes high cohesion within slices and reduces dependencies between them, enhancing maintainability and scalability.
  • Independent Development and Deployment: Each slice can be developed, tested, and deployed independently, allowing teams to work on different features concurrently without causing integration issue

Advantages of Vertical Slice Architecture:

  • Improved Maintainability: Since all code related to a feature is grouped together, understanding and modifying features becomes more straightforward.
  • Enhanced Flexibility: Developers can apply different patterns or technologies within each slice as appropriate, without being constrained by decisions made for other parts of the application.
  • Simplified Testing: Isolated slices allow for more focused and effective testing, as each feature can be tested independently from the rest of the application.

Implementing Vertical Slice Architecture:

  1. Define Features as Slices: Identify the distinct features or use cases of your application and treat each as a separate vertical slice.
  2. Encapsulate All Layers Within Each Slice: Ensure that each slice contains all necessary components, including UI elements, business logic, and data access code, required to implement the feature.
  3. Maintain Independence Between Slices: Design slices to operate independently, minimizing dependencies to reduce the risk of changes in one slice affecting others.
  4. Apply CQRS Where Appropriate: Consider using the Command Query Responsibility Segregation (CQRS) pattern within slices to separate read and write operations, enhancing clarity and scalability.

Project Struture

Following is the folder structure of the project.

Here is a detailed description of the directory structure:

  • Properties: consists of launchSettings.json file, plays a crucial role in configuring how the application starts during development. This file defines various profiles that dictate the environment variables, server settings, and URLs used when launching the application.
  • Common: all the common components reside in this directory. Ex: Enums and Models
  • Config: all the configuration related files reside here including, Dependency Injection related configuration and Endpoint mappings.
  • Database: all the database related files including Database Context, Migrations, etc.
  • Features: this folder is where we implement Vertical Slices, the related features are grouped together. A single feature contains Endpoints, Commands, Queries, Handlers, Models, DTOs, etc.
  • Filters, Middleware and Utils are self-describing.

A partially completed project will look like this with all the files included.

Installing NuGet Packages and Database Configuration

We need following NuGet packages for our project

  1. MongoDB.Driver
  2. MediatR

In this project, we have chosen MongoDB over traditional SQL databases due to its flexibility and scalability, which align well with our application’s requirements.

To work on this project, ensure that MongoDB is installed on your local system. You can achieve this by:

01. Using the Direct Installer:

  • Download: Obtain the latest version of MongoDB Community Edition suitable for your operating system from the official MongoDB website.
  • Install: Follow the installation instructions provided for your specific operating system to complete the setup.

02. Using Docker:

  • Pull the MongoDB Image: Execute the following command to download the official MongoDB image:
docker pull mongodb/mongodb-community-server:latest
  • Run the MongoDB Container: Start a new container with the following command:
docker run --name mongodb -p 27017:27017 -d mongodb/mongodb-community-server:latest

Additionally, we have integrated the MediatR NuGet package to facilitate the implementation of the CQRS (Command Query Responsibility Segregation) pattern, streamlining our application’s architecture and enhancing maintainability.

MediatR simplifies the process of implementing CQRS by providing a straightforward way to manage commands and queries, promoting a clean separation of concerns within the application.

Finally, add this to your appsettings.json file. These config values are used in creating and maintaining the database connection.

 "Database": {
"Name": "pets-dev",
"Url": "mongodb://localhost:27017"
}

Let’s create our first Minimal Endpoints in the next blog post. Happy coding!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Sasanga Edirisinghe
Sasanga Edirisinghe

No responses yet

Write a response