FastSharp.Models
1.0.0-beta.16
dotnet add package FastSharp.Models --version 1.0.0-beta.16
NuGet\Install-Package FastSharp.Models -Version 1.0.0-beta.16
<PackageReference Include="FastSharp.Models" Version="1.0.0-beta.16" />
<PackageVersion Include="FastSharp.Models" Version="1.0.0-beta.16" />
<PackageReference Include="FastSharp.Models" />
paket add FastSharp.Models --version 1.0.0-beta.16
#r "nuget: FastSharp.Models, 1.0.0-beta.16"
#:package FastSharp.Models@1.0.0-beta.16
#addin nuget:?package=FastSharp.Models&version=1.0.0-beta.16&prerelease
#tool nuget:?package=FastSharp.Models&version=1.0.0-beta.16&prerelease
FastSharp
FastSharp is a lightweight library for building APIs in C# and ASP.NET Core (Minimal APIs).
It organizes your application using Modules (contracts) and Endpoints (implementations), so you can structure your API by domain instead of technical layers.
You can also generate full CRUD endpoints in one line — but that's optional.
Why FastSharp?
Minimal APIs are flexible, but as your project grows they often become:
- Repetitive
- Unstructured
- Hard to scale
FastSharp solves this with a simple model:
- Modules → define the route group and API contract
- Endpoints (
IEndpoint) → implement behavior as independent classes AddCRUD→ optional shortcut for standard REST operations
// Inside a module constructor, one call maps 5 REST endpoints backed by EF Core
AddCRUD<Product, int>("/products");
No controllers. No repetition. Just modules organized by domain.
Installation
For contributors and local template validation, build and install the template pack from this repository:
dotnet pack FastSharp.Templates/FastSharp.Templates.csproj -c Release -o ./artifacts
dotnet new install ./artifacts/FastSharp.Templates.1.0.0-beta.13.nupkg
dotnet new fastsharp-api -n MyApi --Database InMemory --EnableSwagger true
cd MyApi
dotnet run
FastSharp.Templates is not yet published as a public NuGet template pack. The local fastsharp-api template scaffolds an EF Core-backed example with generated CRUD, custom IEndpoint implementations, validation, and a selectable provider (InMemory, SqlServer, Postgres, or MySql). FastSharp itself keeps CRUD optional.
Or add FastSharp to an existing Minimal API project:
dotnet add package FastSharp.Modules
dotnet add package FastSharp.Models
FastSharp.Modulesis the core.FastSharp.Modelscontains only the model interfaces — add it to projects that don't need the full core.
⚠️ FastSharp is currently in beta. APIs may change between versions.
Claude Code Skill
FastSharp includes a Claude Code skill for scaffolding common module work while keeping project conventions visible.
Install it from this repository with the Skills CLI:
npx skills add Henry-cmd325/FastSharp
Use it with:
/fastsharp module
/fastsharp crud
/fastsharp endpoint
/fastsharp validation
The skill helps scaffold modules, optional CRUD registrations, custom endpoints, and validation while checking FastSharp route, AddCRUD, assembly scanning, and documentation language conventions.
EF Core CRUD Quick Start
The minimum setup is four code files (steps 2–5 below) plus package restore. This example uses an in-memory database so you can run it immediately.
🧠 Need help choosing a project structure? See How to FastSharp for the recommended ways to organize a FastSharp application as it grows.
1. Install the dependencies
dotnet add package FastSharp.Modules
dotnet add package FastSharp.Models
dotnet add package Microsoft.EntityFrameworkCore.InMemory
2. Your model
// Models/Product.cs
using FastSharp.Models;
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
3. Your DbContext
// Data/ApiDbContext.cs
using Microsoft.EntityFrameworkCore;
public class ApiDbContext : DbContext
{
public ApiDbContext(DbContextOptions<ApiDbContext> options) : base(options) { }
public DbSet<Product> Products => Set<Product>();
}
4. Your module
// Modules/Products/ProductsModule.cs
using yourproject.Context;
using yourproject.Context.Models;
using yourproject.Modules.Products.Dtos;
using yourproject.Modules.Products.Endpoints;
using FastSharp.Modules.Core;
using FastSharp.Modules.Configuration;
namespace yourproject.Modules.Products;
public class ProductsModule : Module<ApiDbContext>
{
public ProductsModule()
{
// ConfigureModule exposes the common Minimal API convention builder surface
// for module-level metadata and policies.
ConfigureModule("/api", opt => opt
.WithTags("Products")
.WithDescription("Endpoints of products module")
);
// Use a manual Id selector for entities that do not implement IModel<int>.
AddCRUD<Product, int>("/products/alternative", p => p.Id, crud =>
{
crud.DisableEndpoint(GenericEndpoint.GetList);
crud.GetList<ProductDto>((endpoint) => endpoint
.WithDescription("Retrieves a list of products (use ?page and ?pageSize for pagination)")
.WithTags("GetList")
);
crud.Create<ProductRequest, ProductDto>((endpoint) => endpoint
.WithDescription("Creates a new product")
.WithTags("Create")
);
});
// Declare custom endpoints for this module (implemented via IEndpoint)
//Include<CheckProductStock>();
}
}
ConfigureModule configures the module route group through IEndpointConventionBuilder, which is the shared Minimal API surface for metadata, authorization policies, filters, and other endpoint conventions. Custom endpoint implementations still receive a RouteGroupBuilder in IEndpoint.Map(...) because they map the actual routes inside the module group.
5. Custom Endpoint
public class CheckProductStock : IEndpoint
{
public void Map(RouteGroupBuilder app)
{
app.MapGet("/{id}/stock", async ([FromRoute] int id) =>
{
return Results.Ok($"Checking stock for product {id}");
})
.WithTags("Stock");
}
}
6. Program.cs
using FastSharp.Modules;
using FastSharp.Modules.Core;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<ApiDbContext>(opt =>
opt.UseInMemoryDatabase("fastsharp-demo"));
builder.Services.AddFastSharpEndpoints();
builder.Services.AddOpenApi();
var app = builder.Build();
app.MapFastSharpEndpoints();
app.MapOpenApi();
app.Run();
Run the project and open /openapi/v1.json — you'll see the generated CRUD endpoints for /api/products/alternative plus any custom endpoints you include in the module.
What does AddCRUD generate?
| Method | Route | Description |
|---|---|---|
GET |
/api/products/alternative |
List, capped at the default max page size (add ?page=1&pageSize=10 for paginated results) |
GET |
/api/products/alternative/{id} |
Get by ID |
POST |
/api/products/alternative |
Create |
PUT |
/api/products/alternative/{id} |
Update |
DELETE |
/api/products/alternative/{id} |
Delete |
Paths use the module prefix from ConfigureModule (these examples use /api) plus the AddCRUD route prefix (here, /products/alternative). Convention: pass a leading slash on every path you own (ConfigureModule, AddCRUD, and custom MapGet / MapPost templates) so routes stay consistent across modules and the library.
🧠 Usage Modes
Choose the module base class for the behavior you need:
| Need | Use |
|---|---|
| Custom routes only; no EF Core dependency | Module + Include<TEndpoint>() |
| Generated CRUD, optionally with custom routes | Module<TDbContext> + AddCRUD(...) |
Custom endpoints only
public sealed class HealthModule : Module
{
public HealthModule()
{
ConfigureModule("/api", module => module.WithTags("Health"));
Include<HealthEndpoint>();
}
}
HealthEndpoint implements IEndpoint and maps its routes on /api. This mode does not require a DbContext or Entity Framework Core.
EF Core CRUD, with optional custom endpoints
public sealed class ProductsModule : Module<ApiDbContext>
{
public ProductsModule()
{
ConfigureModule("/api", module => module.WithTags("Products"));
AddCRUD<Product, int>("/products");
Include<CheckProductStock>();
}
}
AddCRUD is available only on Module<TDbContext> and uses its EF Core DbContext. IEndpoint implementations remain independent behavior classes in either module type.
🆚 How FastSharp differs from FastEndpoints
FastEndpoints focuses on building endpoints with a structured, opinionated approach.
FastSharp focuses on organizing APIs by domain:
- Modules (domains) as first-class units
- Endpoints (
IEndpoint) as implementations inside a module - Optional CRUD generation for common cases
- Closer to Minimal APIs, with less framework overhead
When to choose each:
- Choose FastEndpoints if you want a more opinionated endpoint-centric framework with built-in pipeline features.
- Choose FastSharp if you prefer explicit modular architecture with lightweight abstractions and domain-oriented organization.
Configuration
Disable specific endpoints
AddCRUD<Product, int>("/products", crud =>
{
crud.DisableEndpoint(GenericEndpoint.GetList);
});
Use DTOs
AddCRUD<Product, int>("/products", crud =>
{
crud.Update<ProductDto>();
// Or apply DTOs to all endpoints:
// crud.ConfigureAll<ProductDto>();
});
Add metadata for OpenAPI
AddCRUD<Product, int>("/products", crud =>
{
crud.Get(endpoint =>
endpoint.WithDescription("Get a product by its unique identifier"));
});
Validate custom endpoint requests with FluentValidation
Define your validator and apply WithValidation<T>() to the route handler.
using FastSharp.Modules.Core;
using FluentValidation;
public record UpdateProductStock(int Id, int Quantity);
public sealed class UpdateProductStockValidator : AbstractValidator<UpdateProductStock>
{
public UpdateProductStockValidator()
{
RuleFor(x => x.Id).GreaterThan(0);
RuleFor(x => x.Quantity).NotEqual(0);
}
}
public sealed class UpdateProductsStock : IEndpoint
{
public void Map(RouteGroupBuilder app)
{
app.MapPost("/products/update-stock", (UpdateProductStock request) => Results.NoContent())
.WithValidation<UpdateProductStock>();
}
}
If no IValidator<T> is registered for the request type, the validation filter does nothing and the endpoint continues normally. Validators in assemblies passed to AddFastSharpEndpoints(...) are registered automatically through FluentValidation assembly scanning. See Validation with FluentValidation.
Add custom endpoints to the same module
public ProductsModule()
{
ConfigureModule("/api", module => module.WithTags("Products"));
AddCRUD<Product, int>("/products");
Include<CheckProductStock>();
}
public class CheckProductStock : IEndpoint
{
public void Map(RouteGroupBuilder app)
{
app.MapGet("/{id}/stock", async ([FromRoute] int id) =>
{
return Results.Ok($"Checking stock for product {id}");
})
.WithTags("Stock");
}
}
Custom IEndpoint types are mapped on the module route group (the ConfigureModule prefix), not nested under each AddCRUD prefix. With /api as the module prefix, MapGet("/{id}/stock", ...) becomes GET /api/{id}/stock, alongside GET /api/products, GET /api/products/{id}, etc. They still share group-level OpenAPI metadata from ConfigureModule.
Use ConfigureModule for module-wide conventions such as tags, descriptions, authorization, and filters. Use IEndpoint.Map(RouteGroupBuilder app) when you need to define concrete custom routes.
Module discovery: With no arguments,
AddFastSharpEndpoints()andMapFastSharpEndpoints()scan the calling assembly (typically the project that containsProgram.cs). If your modules live in another class library, pass that assembly explicitly. See Assembly scanning.
OpenAPI UI: The snippet above exposes the OpenAPI document only. For Swagger UI in Development (like the repo sample), add
Swashbuckleor your preferred UI and callMapOpenApi/ UI middleware where appropriate.
Architecture
FastSharp is built on Modular Slices — group your logic by domain, not by technical layers.
YourProject/
└── Modules/
├── Products/
│ ├── ProductsModule.cs
│ ├── CheckProductStock.cs
│ └── ProductDto.cs
└── Orders/
├── OrdersModule.cs
└── OrderDto.cs
Each module is a self-contained unit: its routes, its DTOs, its custom endpoints. At startup, FastSharp registers every concrete IFastModule and IEndpoint type found in the assemblies you pass to AddFastSharpEndpoints / MapFastSharpEndpoints (default: the calling assembly only). There is no manual “register this module” list beyond that scan.
Requirements
- .NET 10 or higher
- For custom endpoints only:
Module,IEndpoint, and ASP.NET Core Minimal APIs - For generated CRUD: Entity Framework Core, a registered
DbContext, and aModule<TDbContext> - Entities used with the parameterless
AddCRUD<TEntity, TKey>(...)overload must implementIModel<TId>; plain POCOs use the overload with an id selector
Docs
- Contributing
- Modular architecture
- Customization
- Validation with FluentValidation
- Assembly scanning
- Roadmap
- How to FastSharp
Minimal APIs, EF Core, and Mapster
FastSharp registers routes using the same building blocks as ASP.NET Core Minimal APIs (MapGet, MapGroup, route handlers, OpenAPI metadata, etc.). You do not need to be an expert to use the built-in CRUD conventions, but anything beyond that (custom IEndpoint handlers, policies, filters, or fine-grained OpenAPI) is easier if you already know how Minimal APIs work.
The generic CRUD endpoints run on Entity Framework Core: they use your DbContext, DbSet<T>, LINQ queries, and SaveChangesAsync under the hood. Understanding EF Core basics (configuring the context, change tracking, relationships, and migrations in real apps) helps when your entities are more than simple tables.
When you use DTOs (ConfigureAll, per-endpoint generic types, etc.), FastSharp uses Mapster to map between entities and DTOs (for example Adapt<T>()). Customizing those mappings (flattening, ignoring members, global settings) follows Mapster’s configuration model.
- Minimal APIs overview — Microsoft Learn
- Entity Framework Core documentation — Microsoft Learn
- Mapster wiki — GitHub
License
Licensed under the Apache License, Version 2.0.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on FastSharp.Models:
| Package | Downloads |
|---|---|
|
FastSharp.Modules
FastSharp: Convention-over-configuration CRUDs and modular endpoints for .NET Minimal APIs. Build faster, keep it clean. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-beta.16 | 82 | 7/28/2026 |
| 1.0.0-beta.14 | 67 | 7/28/2026 |
| 1.0.0-beta.12 | 129 | 6/11/2026 |
| 1.0.0-beta.11 | 74 | 5/29/2026 |
| 1.0.0-beta.10 | 70 | 5/29/2026 |
| 1.0.0-beta.8 | 75 | 4/14/2026 |
| 1.0.0-beta.7 | 75 | 4/1/2026 |
| 1.0.0-beta.6 | 70 | 3/31/2026 |
| 1.0.0-beta.5 | 76 | 3/31/2026 |
| 1.0.0-beta.4 | 73 | 3/23/2026 |
| 1.0.0-beta.3 | 69 | 3/21/2026 |
| 1.0.0-beta.2 | 77 | 2/21/2026 |
| 1.0.0-alpha.4 | 83 | 2/12/2026 |
| 1.0.0-alpha.1 | 76 | 2/11/2026 |