DEV Community

mohamed Tayel
mohamed Tayel

Posted on • Updated on

What is Clean Architecture: Part 18 - Adding API

Throughout the previous articles, we have done a lot of groundwork building the essential layers of our application, focusing on clean, maintainable architecture. However, while our code base builds successfully, we haven’t yet exposed any working functionality for consumers to interact with. That’s about to change. In this module, we will focus on creating the API layer, using ASP.NET Core 8, which will act as the gateway to the core functionality of our application.

Getting Started with the API

The creation of the API project is relatively straightforward, but there are key decisions to consider regarding how to structure the API itself. We will look at several aspects, including how MediatR integrates with the API, which code belongs in the API controllers, and how to structure the responses to ensure proper data handling. Finally, we'll set up Swagger to document the API, ensuring consumers have a clear understanding of its functionality.

Creating the API Project

Let’s begin by creating the API project. This task is simple, but it will act as the interface between the outside world and our application’s core logic. We have already constructed the Core and Infrastructure layers, and now we’ll be adding the final piece of the architecture—the API.

Here’s a quick look at how this new layer fits into our overall Clean Architecture:

API Layer

The API opens up the backend services, allowing various clients (e.g., web apps, mobile apps) to interact with the core business logic and data. Unlike traditional UIs like ASP.NET Core MVC or Razor Pages, this API will be the primary interface for communication. This approach allows for greater flexibility, supporting multiple client types and even system-to-system integrations.

Project Setup

Before we begin coding, let’s add references to the Core, Infrastructure, and Persistence layers within the API project to ensure proper interaction with the existing architecture. Update the csproj file to include these references:

<ItemGroup>
  <ProjectReference Include="..\GloboTicket.TicketManagement.Application\GloboTicket.TicketManagement.Application.csproj" />
  <ProjectReference Include="..\GloboTicket.TicketManagement.Infrastructure\GloboTicket.TicketManagement.Infrastructure.csproj" />
  <ProjectReference Include="..\GloboTicket.TicketManagement.Persistence\GloboTicket.TicketManagement.Persistence.csproj" />
</ItemGroup>
Enter fullscreen mode Exit fullscreen mode

These references allow the API project to utilize the business logic from Core and the services provided by Infrastructure and Persistence.

Configuring the API in ASP.NET Core 8

Next, we will configure the Program.cs file. Instead of cluttering it with multiple lines of service and pipeline configuration, we will leverage extension methods to keep things clean and modular.

StartupExtensions.cs

We’ll define two extension methods: one to configure services and the other to set up the middleware pipeline.

using GloboTicket.TicketManagement.Application;
using GloboTicket.TicketManagement.Infrastructure;
using GloboTicket.TicketManagement.Persistence;

namespace GloboTicket.TicketManagement.Api
{
    public static class StartupExtensions
    {
        public static WebApplication ConfigureServices(
           this WebApplicationBuilder builder)
        {
            builder.Services.AddApplicationServices();
            builder.Services.AddInfrastructureServices(builder.Configuration);
            builder.Services.AddPersistenceServices(builder.Configuration);
            builder.Services.AddControllers();

            builder.Services.AddCors(options => options.AddPolicy(
                "open",
                policy => policy.WithOrigins(
                    builder.Configuration["ApiUrl"] ?? "https://localhost:7020")
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials()
                .SetIsOriginAllowed(origin => true)
            ));

            // Optional: Enable Swagger for API documentation
            // builder.Services.AddSwaggerGen();

            return builder.Build();
        }

        public static WebApplication ConfigurePipeline(this WebApplication app)
        {
            app.UseCors("open");

            app.UseHttpsRedirection();
            app.MapControllers();

            return app;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Program.cs

Once the extension methods are defined, we can use them to set up the API in a very concise and clean way:

using GloboTicket.TicketManagement.Api;

var builder = WebApplication.CreateBuilder(args);

var app = builder
       .ConfigureServices()
       .ConfigurePipeline();

app.Run();
Enter fullscreen mode Exit fullscreen mode

This setup ensures that all the services and middleware are registered properly without cluttering the main entry point of the API.

What’s Inside the Extensions?

  1. ConfigureServices:

    • Registers the application, infrastructure, and persistence services.
    • Adds support for controllers to handle incoming API requests.
    • Configures CORS (Cross-Origin Resource Sharing) to allow the API to be accessed by specified front-end clients, such as the one hosted at ApiUrl or BlazorUrl.
    • Optionally sets up Swagger for API documentation.
  2. ConfigurePipeline:

    • Applies the CORS policy.
    • Redirects all HTTP traffic to HTTPS for security.
    • Maps the controllers to the routes, enabling the API to respond to HTTP requests.

Bringing it All Together

We’ve now set up the API to interface with the Core and Infrastructure layers, following Clean Architecture principles. The API will expose functionality for client applications to consume, while maintaining a clear separation of concerns.

By leveraging the ASP.NET Core 8 framework, we are taking advantage of the latest optimizations, ensuring that our API is both efficient and scalable. With the modular setup we’ve implemented, maintaining and extending the API will be straightforward as the project grows.

In the next module, we’ll explore how to structure the API controllers and implement specific use cases, including the use of MediatR to handle commands and queries, ensuring our controllers remain lean and focused on their primary role—handling HTTP requests and responses.

Stay tuned for more as we continue building out the API functionality!
For the complete source code, you can visit the GitHub repository: https://github.com/mohamedtayel1980/clean-architecture

Top comments (0)