Getting Started

OtterApi is an ASP.NET Core library that automatically generates a full REST API on top of your EF Core models. Register your entities once and get complete CRUD endpoints, filtering, sorting, pagination, authorization, and Swagger docs — no controllers, no repositories.

Installation

Install the package via the .NET CLI:

Shell
dotnet add package OtterApi

Or add the PackageReference directly to your .csproj:

MyProject.csproj
<PackageReference Include="OtterApi" Version="2.0.0" />

Dependencies

The following packages are installed automatically as transitive dependencies:

PackageVersion
Microsoft.EntityFrameworkCore8.0.0
Swashbuckle.AspNetCore.SwaggerGen6.3.1

Requirements

Quick Start

The minimal setup requires two calls in Program.cs: one to register services and one to register the middleware.

Program.cs
var builder = WebApplication.CreateBuilder(args);

// Register your DbContext as usual
builder.Services.AddDbContext<AppDbContext>(opt =>
    opt.UseSqlite("Data Source=app.db"));

// 1. Register OtterApi services
builder.Services.AddOtterApi<AppDbContext>(options =>
{
    options.Path = "/api";
    options.Entity<Product>("products");
});

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

// 2. Register OtterApi middleware — must come after auth
app.UseOtterApi();

app.MapControllers();
app.Run();

Generated endpoints

After startup, the following routes are available for /api/products:

MethodRouteDescription
GET/api/productsList all records
GET/api/products/{id}Single record by primary key
POST/api/productsCreate a new record
PUT/api/products/{id}Full update of an existing record
PATCH/api/products/{id}Partial update (RFC 7396 JSON Merge Patch)
DELETE/api/products/{id}Delete a record
GET/api/products/countTotal count respecting filters
GET/api/products/pagedresultPaginated envelope (when enabled)
💡
UseOtterApi() must be placed after UseAuthentication() and UseAuthorization(), and before UseEndpoints() / MapControllers().

Example entity

Any EF Core entity registered as DbSet<T> in your DbContext can be used with OtterApi.

Product.cs
public class Product
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [Required]
    [MaxLength(200)]
    public string Name { get; set; }

    public decimal Price { get; set; }
    public int     Stock { get; set; }
    public bool    IsActive { get; set; }
    public DateTime CreatedAt { get; set; }

    public int       CategoryId { get; set; }
    public Category? Category   { get; set; }
}

Primary key detection

OtterApi detects the primary key in the following order:

  1. A property marked with [Key]
  2. A property named Id (case-insensitive)
  3. A property named {ClassName}Id (e.g. ProductId for Product)

If none is found, the entity is treated as keyless (read-only, GET only). See Advanced.

Next steps