ApiEndpoints
A project for supporting API Endpoints in ASP.NET Core web applications.
Install / Use
/learn @ardalis/ApiEndpointsREADME
ASP.NET Core API Endpoints
A project for supporting API Endpoints in ASP.NET Core web applications.
Fast Endpoints
If you're on .NET 6 or later (if you're no longer on .NET 4.x you should be on at least .NET 8) you're probably better off using Minimal APIs than Controllers. MVC is a dull edge technology at this point. If you like the organization used by this library and the REPR Pattern in general, I am now recommending the FastEndpoints library. It has a lot of additional functionality you can use or not, but its core api endpoint functionality is very solid and fast.
Give a Star! :star:
If you like or are using this project to learn or start your solution, please give it a star. Thanks!
Discover a Practical Example
If you're eager to dive into a practical example of using Ardalis.ApiEndpoints, check out our Getting Started guide. This guide walks you through setting up your environment and creating your first API endpoint using the latest features in version 4.x.
Upgrade to 4.x Notes
The fluent generics and base types involved in ApiEndpoints were updated in version 4.x, resulting in breaking changes. The updates required should be pretty straightforward, and have a few additional features that weren't supported in previous versions.
The two main changes introduced in v4 are:
- Base classes should now use
EndpointBaseSyncorEndpointBaseAsync WithResponsehas been modified toWithResultorWithActionResult
The result of an endpoint corresponds to the return type from the Handle method. Since ASP.NET Core MVC refers to these as some variation of ActionResult, that's the term we are using in this package now as well. The Response your endpoint may return refers to any data/DTO that is being sent to the client as part of the Result. If you wish to preserve your existing v3 functionality that specified WithResponse<T> you should be able to replace all such occurrences with WithActionResult<T>. However, if you need to specify a different kind of Result, such as a FileResult, you can now use something like WithResult<FileResult> to achieve this.
An endpoint that previously inherited from the synchronous BaseEndpoint should now inherit from EndpointBaseSync. Additionally, the WithResponse option now has optional non-generic versions, but if you were intending to return an ActionResult<T> you would now use WithActionResult<T> in your class definition, like so:
- public class ForecastEndpoint : BaseEndpoint
- .WithRequest<ForecastRequestDto>
- .WithResponse<IEnumerable<WeatherForecast>>
+ public class ForecastEndpoint : EndpointBaseSync
+ .WithRequest<ForecastRequestDto>
+ .WithActionResult<IEnumerable<WeatherForecast>>
The above change typically would not require any change to the Handle method. Endpoints that inherited from BaseAsyncEndpoint would now use EndpointBaseAsync. You can also just inherit from EndpointBase directly (without the .With* additions) which will provide you with a controller with a single Handle method without restrictions on parameter amount and type, if you need more flexibility than the fluent generic interface provides.
Upgrade to 3.x Notes
For version 3.0 we implemented a new way to define the base classes using "fluent generics". You can watch a video of what you need to know to apply them to your site here.
Table of Contents
2. Introducing ASP.NET Core API Endpoints
10. Projects Using ApiEndpoints
11. Success Stories and Testimonials
1. Motivation
MVC Controllers are essentially an antipattern. They're dinosaurs. They are collections of methods that never call one another and rarely operate on the same state. They're not cohesive. They tend to become bloated and to grow out of control. Their private methods, if any, are usually only called by a single public method. Most developers recognize that controllers should be as small as possible (unscientific poll), but they're the only solution offered out of the box, so that's the tool 99% of ASP.NET Core developers use.
You can use tools like MediatR to mitigate the problem. You can read a detailed article about how to migrate from Controllers to Endpoints using MediatR. The short version is that MediatR enables you to have single-line action methods that route commands to handlers. This is objectively a better approach, resulting in more cohesive classes that better follow OO principles. But what if you didn't even need that extra plumbing?
That's what ASP.NET Core API Endpoints are all about.
Side note: Razor Pages
The .NET team already did this exact thing with razor pages. They recognized that dealing with Views, ViewModels, Controllers, and Actions was way more complicated than necessary. It required a developer to jump around between at least 3 (and often more) different folders in order to add or modify a new page/view to their project. Razor pages addressed this by rethinking the model for page-based ASP.NET Core MVC endpoints.
Razor Pages group each page's razor markup, its related action(s), and its model into two linked files. It uses the same MVC features as the rest of the platform, so you still get routing, model binding, model validation, filters, the works. You literally give up nothing. But now when you need to add or modify a page you need to look at exactly 2 files, which are linked in the IDE so you don't need to scroll around the file system looking for them.
2. Introducing ASP.NET Core API Endpoints
ASP.NET Core API Endpoints are essentially Razor Pages for APIs. They break apart bloated controllers and group the API models used by individual endpoints with the endpoint logic itself. They provide a simple way to have a single file for the logic and linked files for the model types.
When working with ASP.NET Core API Endpoints your project won't need any Controller classes. You can organize the Endpoints however you want. By feature. In a giant Endpoints folder. It doesn't matter - they'll work regardless of where you put them.
Most REST APIs have groups of endpoints for a given resource. In Controller-based projects you would have a controller per resource. When using API Endpoints you can simply create a folder per resource, just as you would use folders to group related pages in Razor Pages.
Instead of Model-View-Controller (MVC) the pattern becomes Request-EndPoint-Response(REPR). The REPR (reaper) pattern is much simpler and groups everything that has to do with a particular API endpoint together. It follows SOLID principles, in particular SRP and OCP. It also has all the benefits of feature folders and better follows the Common Closure Principle by grouping together things that change together.
3. Getting Started
Set Up an Empty Web API Project
Overview
When starting a new Web API project using .NET, you might want to begin with an empty project structure to have more control over dependencies and configurations.
Setting Up the Project
-
Create the Project:
Start by creating a new empty web API project. You can do this using the .NET CLI:
dotnet new web -n MyWebApi cd MyWebApiThis creates a basic project structure for a web application.
-
Update Program.cs:
Open the
Program.csfile, which serves as the entry point for your application. By default, it might contain the following code:var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); // app.MapGet("/", () => "Hello World!"); app.Run();Remove the
app.MapGet("/", () => "Hello World!");line as it sets up a minimal endpoint which we'll replace with controller routing. -
Configure Services and Routing:
Modify the
Program.csfile to include controller services and routing:var builder = WebApplication.CreateBuilder(args); // Add controllers builder.Services.AddControllers();
Related Skills
gh-issues
333.7kFetch GitHub issues, spawn sub-agents to implement fixes and open PRs, then monitor and address PR review comments. Usage: /gh-issues [owner/repo] [--label bug] [--limit 5] [--milestone v1.0] [--assignee @me] [--fork user/repo] [--watch] [--interval 5] [--reviews-only] [--cron] [--dry-run] [--model glm-5] [--notify-channel -1002381931352]
oracle
333.7kBest practices for using the oracle CLI (prompt + file bundling, engines, sessions, and file attachment patterns).
tmux
333.7kRemote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
xurl
333.7kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
