C# Web API – A Complete Look at Structuring APIs with Derek Comartin's Approach
When starting a C# Web API project, developers are often faced with an overwhelming number of choices for how to structure their code. Should you follow a layered ASP.NET Core Web API pattern? Should you stick to the controllers folder from the default template in Visual Studio? Or should you try a more modern style like Minimal APIs?
In his video, "Keep Your Project Structure Simple!", Derek Comartin from CodeOpinion.com takes an opinionated but refreshingly practical stance. He walks through his ideas for building and organizing a Web API in a way that works for real-world software systems, focusing on what actually matters: simplicity.
This article follows Derek’s video step by step, to guide you through how to structure an ASP.NET Core Web API project for clarity, maintainability, and real-world scalability.
Looking at Common API Structures
Derek begins by asking the question most developers hit when creating a new Web API project in Visual Studio:
“How should you structure your HTTP API?”
He immediately acknowledges that Web API projects can be organized in many ways. Among the most common folder structures Derek sees:
Grouping by technical concerns – putting models in a Models folder, controllers in a Controllers folder, and services in Services.
Using Clean Architecture or Onion Architecture – where projects are split by layers (API, Application, Domain, Infrastructure) to guide dependencies.
- Combining Domain-Driven Design (DDD) with vertical slice architecture – grouping endpoints by feature but still having domain-rich objects.
Derek stresses that each of these patterns can create a RESTful API that uses the HTTP methods you’d expect (GET, POST, PUT, DELETE) to work with resources. But he warns against reading too much into folder structures alone:
“You might see entities, aggregates, or domain services, but that doesn’t mean the code is really doing domain-driven design—it’s just using those patterns.”
Starting With Simplicity, Not Complexity
Derek says his goal is straightforward:
“One of the main things I wanted to achieve with this structure is simplicity.”
Rather than jumping into a heavy .NET Framework style architecture or replicating patterns from textbooks, Derek chooses ASP.NET Core Minimal APIs. Why? Because they make it easy to create APIs without the overhead of controllers and boilerplate code.
When you build a new Web API project in Visual Studio or even Visual Studio Code, you might start with the New Project Dialog and select ASP.NET Core Web API. By default, you’ll get controllers, folders, and a lot of scaffolding. Derek argues that starting smaller—a simple, clean structure—is often better.
The Core Structure of Derek’s Web API
Derek introduces his web application structure using .NET Core. It’s built to support common HTTP services and RESTful APIs that allow different software applications to communicate.
Here’s how he organizes his web API project:
Endpoints File – A single file to see all available routes in the API. Instead of digging through multiple controllers, Derek wants a quick overview of every get method, post method, put request, or delete request the API supports.
Common Folder – Holds shared code like filters and extensions used across different software systems.
Feature Folders – Following the vertical slice philosophy, each new resource or existing resource gets its own folder. For example, a Posts folder might include everything needed for GET /posts/{id}, POST /posts, PUT /posts/{id}, and DELETE /posts/{id}.
- Data Folder – Contains the data model and entity mappings. Here, Entity Framework Core might be used for seamless database integration.
By grouping endpoints by feature, Derek avoids spreading logic across multiple unrelated folders.
Why He Doesn’t Force Domain-Driven Design
Derek has used Domain-Driven Design in the past, but in this C# Web API structure he makes a key choice:
“We’re not going to be using domain-driven design.”
Instead, he “just lets data be data.” His data models are plain classes with simple properties like:
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
}public class Post
{
public int Id { get; set; }
public string Title { get; set; }
}No unnecessary behavior is crammed in. When you send a POST request to create a new resource, the API simply saves it. When you send a DELETE request with an id parameter, it deletes that resource.
This approach embraces the architectural style of Representational State Transfer (REST) by treating API endpoints as verbs (get method, post method, put method, delete method) acting on resources like Post, User, or Comment.
Walking Through the Solution in Visual Studio
At this point, Derek opens his Visual Studio solution and gives us a tour:
The Endpoints file lists every route—whether it’s a GET request fetching data, a POST request adding a new resource, a PUT request updating data, or a DELETE method removing an existing resource.
The Data folder holds mappings for entities like Post, User, and Comment—connected to a database via Entity Framework.
The Common folder contains shared logic for HTTP services like validation filters and extensions.
- Each Feature Folder (Posts, Comments, Authentication) has all the code needed for that resource.
This clean project folder layout avoids the mess of digging through an overly complex project dialog or a scattered controllers folder.
Breaking Down an Endpoint
Derek explains that each endpoint in his ASP.NET Core Web API is a self-contained unit of work with three clear steps:
Mapping – Defines the HTTP method and route. For example, a delete request might map DELETE /posts/{id} to a handler method.
Request & Response Contracts – Each endpoint has its own request body and response type. This makes HTTP services clearer and avoids creating layers of duplicate DTOs.
- Logic – The actual handler method, where the API fetches from the database, updates a data model, or returns a status code like return CreatedAtAction or return NoContent.
Because Derek uses Minimal APIs, these handlers are static methods. With ASP.NET Core, this means you can inject dependencies directly—no bulky controller class needed.
Why Minimal APIs Feel Right
Derek praises Minimal APIs for their simplicity. With ASP.NET Core’s minimal template, you can start a web API project with just a few lines in Program.cs:
var app = WebApplication.CreateBuilder(args).Build();var app = WebApplication.CreateBuilder(args).Build();From there, you add your get methods, post methods, and put requests in a straightforward way.
This simplicity helps avoid over-engineering—something Derek sees all too often when developers blindly copy nuget package templates or force new controller classes for every minor endpoint.
How Complexity Can Evolve Over Time
Derek gives a real example: the “like a post” feature.
At first, it’s simple—check if a like exists, add one if not.
But later, the software application might need to return a like count instantly for web pages or mobile devices.
- To scale, you might denormalize data by adding a LikeCount property to the Post data model.
This opens new challenges:
Every put method or delete method that affects likes must correctly update the count.
- If someone adds a like record without calling the API, the count is wrong.
Derek shows that as complexity grows, you might add patterns like:
Repository pattern for encapsulating data access.
Aggregate roots to handle behaviors (like incrementing LikeCount).
- Outbox pattern to guarantee events (like “PostLiked”) are published.
But his key point is clear:
“Don’t start here. Start with simple and evolve only if needed.”
Wrapping Up with Derek’s Takeaway
Derek ends by returning to his main lesson for C# Web API developers:
“Start with simple.”
When you use ASP.NET Core Web API or ASP.NET Web API in Visual Studio, it’s easy to over-engineer from day one—adding every folder, pattern, and NuGet package you’ve ever seen.
But Derek warns: don’t apply solutions blindly. Understand the HTTP methods you need, the data you’re working with, and the software systems you’re enabling communication between. Build your RESTful APIs step by step.
For those using Visual Studio Code or any other integrated development environment, his advice holds true: Whether it’s a new project or an existing resource, keep your project structure as simple as possible, and only add patterns when real-world complexity demands it.
Conclusion
Derek Comartin’s video is more than just a guide for building a C# Web API—it’s a reminder that good architecture starts with clarity, not clutter. By walking through his real-world ASP.NET Core Web API setup in Visual Studio, he shows how Minimal APIs, feature folders, and straightforward data models can form the foundation for RESTful APIs that enable seamless communication between different software applications without overcomplicating the design.
If you want to see this approach in action and hear Derek’s perspective firsthand, his video is an excellent resource. His channel is filled with equally insightful discussions on software systems, web services, and ASP.NET Core development—a must-follow for any developer looking to improve their craft and keep their projects clean, practical, and future-friendly.
