A .NET 10 minimal API framework collection aimed to support AOT.
dotnet add package Sharkable
using Sharkable; var builder = WebApplication.CreateBuilder(args); builder.Services.AddShark(); var app = builder.Build(); app.UseShark(); app.Run();
For AOT mode, pass assemblies explicitly:
builder.Services.AddShark([typeof(Program).Assembly]);
Create a class implementing ISharkEndpoint. It's automatically discovered and registered.
public class TestEndpoint : ISharkEndpoint { public void AddRoutes(IEndpointRouteBuilder app) { app.MapGet("hello", () => Results.Ok("hi")); app.MapPost("create", (CreateRequest req) => Results.Ok(req)); } }
URL becomes api/test/hello, api/test/create (group name derived from class name).
Group multiple endpoints under the same URL prefix and OpenAPI tag.
[EndpointGroup("admin")] [SharkTag("admin")] public class UserEndpoint : ISharkEndpoint { public void AddRoutes(IEndpointRouteBuilder app) { app.MapGet("users", () => Results.Ok(users)); } } [EndpointGroup("admin")] [SharkTag("admin")] public class RoleEndpoint : ISharkEndpoint { public void AddRoutes(IEndpointRouteBuilder app) { app.MapGet("roles", () => Results.Ok(roles)); } }
Both under api/admin/users and api/admin/roles, sharing OpenAPI tag admin. OperationIds are auto-generated via {group}_{httpMethod}_{path}.
Mark classes with attributes or marker interfaces for auto-registration.
[ScopedService] // or [SingletonService], [TransientService] public class Monitor : IMonitor { public void Show() { } } // Or use marker interfaces: public class Monitor : IMonitor, IScoped { }
Converts unhandled exceptions to UnifiedResult<T> JSON responses automatically.
app.UseShark(opt => { opt.ExceptionHandlerOptions.Map<MyException>(HttpStatusCode.Forbidden); });
Consistent API response format across all endpoints.
return data.AsOkResult(); return "error".AsBadRequest(); return "no access".AsUnauthorized(); // Or with auto-wrap: app.UseShark(opt => opt.EnableAutoWrap = true); app.MapGet("hello", () => "world"); // -> { "statusCode": 200, "data": "world", ... }
Automatic request validation with FluentValidation.
builder.Services.AddShark(opt => opt.EnableValidation = true); public class CreateUserValidator : AbstractValidator<CreateUserRequest> { public CreateUserValidator() { RuleFor(x => x.Email).NotEmpty().EmailAddress(); } }
Invalid requests return 400 with a UnifiedResult error body.
OpenAPI spec at /openapi/v1.json, Scalar UI at /scalar/v1. Enabled by default.
builder.Services.AddShark(opt => { opt.ConfigureOpenApi(options => { /* configure OpenAPI options */ }); });
Auto-generate CRUD endpoints with SqlSugar.
builder.Services.AddShark(opt => { opt.ConfigureAutoCrud(sqlSugar => { /* configure SqlSugar */ }); });
Configure URL naming conventions globally.
builder.Services.AddShark(opt => { opt.Format = EndpointFormat.SnakeCase; // CamelCase, ToLower, UnChanged opt.ApiPrefix = "api"; // default });
Sharkable is designed for AOT compilation. Pass assemblies explicitly and register JsonSerializerContext:
builder.Services.AddShark([typeof(Program).Assembly]);
Old-style [SharkEndpoint] + [SharkMethod] endpoints use reflection and will NOT work in AOT mode.
Full documentation: https://sharkableio.github.io
MIT