Configuration Reference

Everything Ninjadog generates is driven by a single ninjadog.json file in your project root.

Table of contents
  1. Quick Reference
  2. Overview
  3. JSON Schema
  4. Config Section
    1. Core Fields
    2. CORS
    3. Features
    4. Database
    5. Authentication
    6. Rate Limiting
    7. Versioning
  5. Entities
    1. Properties
    2. Supported Types
  6. Relationships
  7. Enums
  8. Seed Data
    1. Inline JSON Array
    2. CSV File Reference
  9. Native AOT Support
    1. What changes with AOT enabled
    2. Generated files
  10. Complete Example
  11. Next Steps

Quick Reference

The following skeleton shows every configuration option at a glance. Required fields are marked with a comment. All other fields are optional.

{
  "$schema": "./ninjadog.schema.json",
  "config": {
    "name": "MyApi",                          // required
    "version": "1.0.0",                       // required
    "description": "My REST API",             // required
    "rootNamespace": "MyApi",                 // required
    "outputPath": "src/applications/MyApi",   // default: "."
    "saveGeneratedFiles": true,               // default: true
    "cors": {
      "origins": ["https://example.com"],     // required if cors is set
      "methods": ["GET", "POST"],             // optional
      "headers": ["Content-Type"]             // optional
    },
    "features": {
      "softDelete": false,                    // default: false
      "auditing": false,                      // default: false
      "aot": false                            // default: false
    },
    "database": {
      "provider": "sqlite"                    // "sqlite" | "postgresql" | "sqlserver"
    },
    "auth": {
      "provider": "jwt",                      // only "jwt" supported
      "issuer": "https://myapp.com",          // default: "https://localhost"
      "audience": "myapp-api",                // default: "api"
      "tokenExpirationMinutes": 60,           // default: 60
      "roles": ["Admin", "User"],             // optional
      "generateLoginEndpoint": true,          // default: true
      "generateRegisterEndpoint": true        // default: true
    },
    "rateLimit": {
      "permitLimit": 100,                     // default: 100
      "windowSeconds": 60,                    // default: 60
      "segmentsPerWindow": 6                  // default: 6
    },
    "versioning": {
      "strategy": "UrlPath",                  // "UrlPath" | "HeaderBased"
      "defaultVersion": 1,                    // default: 1
      "prefix": "v",                          // default: "v"
      "headerName": "X-Api-Version"           // default: "X-Api-Version"
    }
  },
  "enums": {
    "Priority": ["Low", "Medium", "High"]
  },
  "entities": {
    "Product": {
      "properties": {
        "Id": { "type": "Guid", "isKey": true },
        "Name": { "type": "string", "required": true, "minLength": 1, "maxLength": 200 },
        "Price": { "type": "decimal", "min": 0, "max": 9999 },
        "Email": { "type": "string", "pattern": "^[^@]+@[^@]+\\.[^@]+$" },
        "Status": { "type": "Priority" }
      },
      "relationships": {
        "Orders": { "relatedEntity": "Order", "type": "OneToMany" }
      },
      "seedData": [
        { "Id": "...", "Name": "Sample", "Price": 9.99, "Email": "a@b.com", "Status": 0 }
      ]
    }
  }
}

New to Ninjadog? Start with the Getting Started tutorial – it walks you through creating your first API from a minimal config. Come back here when you need the full reference.

Overview

The ninjadog.json file is the central configuration for your project. It defines the project metadata, feature flags, entity schemas, enums, and seed data. Every ninjadog build invocation reads this file and produces the corresponding .NET source code.

JSON Schema

Ninjadog ships a JSON Schema file alongside your configuration. Adding a $schema property to your ninjadog.json enables autocomplete, inline documentation, and validation in editors that support JSON Schema (VS Code, JetBrains IDEs, and others).

{
  "$schema": "./ninjadog.schema.json",
  "config": { ... },
  "entities": { ... }
}

Run ninjadog init to generate both ninjadog.json and ninjadog.schema.json automatically. If you already have a project, run ninjadog validate to check your configuration against the schema.

Config Section

The config object contains project-level settings.

{
  "config": {
    "name": "MyApi",
    "version": "1.0.0",
    "description": "My REST API",
    "rootNamespace": "MyApi",
    "outputPath": "src/applications/MyApi",
    "saveGeneratedFiles": true,
    "cors": { ... },
    "features": { ... },
    "database": { ... },
    "auth": { ... },
    "rateLimit": { ... },
    "versioning": { ... }
  }
}

Core Fields

Field Type Required Default Description
name string Yes Project name used in the generated .sln and .csproj files.
version string Yes Semantic version of your API project.
description string Yes Short description included in the generated project metadata.
rootNamespace string Yes Root C# namespace for all generated code.
outputPath string No "." Directory where generated files are written, relative to ninjadog.json.
saveGeneratedFiles boolean No true When true, generated files are saved to disk.

CORS

The optional cors object configures the CORS policy applied to the generated API.

Field Type Required Description
origins string[] Yes Allowed origins for cross-origin requests.
methods string[] No Allowed HTTP methods. When omitted, all methods are allowed.
headers string[] No Allowed request headers. When omitted, all headers are allowed.

If you omit the cors block entirely, Ninjadog defaults to allowing https://localhost:7270 as the only origin.

Features

The optional features object enables cross-cutting concerns.

Field Type Default Description
softDelete boolean false Adds IsDeleted and DeletedAt columns; replaces DELETE with UPDATE.
auditing boolean false Adds CreatedAt and UpdatedAt columns managed automatically by the repository.
aot boolean false Enables Native AOT publishing support. See AOT Support below.

Database

The optional database object controls the target database provider.

Field Type Default Description
provider string "sqlite" Database provider. Supported values: sqlite, postgresql, sqlserver.

The provider affects SQL dialect (e.g., LIMIT vs OFFSET/FETCH), column type mappings, timestamp functions, NuGet dependencies, and the generated connection factory class.

Authentication

The optional auth object enables JWT authentication and authorization for the generated API.

{
  "config": {
    "auth": {
      "provider": "jwt",
      "issuer": "https://myapp.com",
      "audience": "myapp-api",
      "tokenExpirationMinutes": 120,
      "roles": ["Admin", "User"],
      "generateLoginEndpoint": true,
      "generateRegisterEndpoint": true
    }
  }
}
Field Type Default Description
provider string "jwt" Authentication provider. Currently only jwt is supported.
issuer string "https://localhost" JWT token issuer URL.
audience string "api" JWT token audience identifier.
tokenExpirationMinutes integer 60 Token lifetime in minutes.
roles string[] Role names for authorization policies. When set, generates named policies.
generateLoginEndpoint boolean true Generates a POST /api/auth/login endpoint.
generateRegisterEndpoint boolean true Generates a POST /api/auth/register endpoint.

When auth is enabled:

Replace the Jwt:Secret value in appsettings.json with a strong secret key (minimum 32 characters) before deploying to production. Never commit real secrets to source control.

When the auth block is absent, all endpoints use AllowAnonymous() and no auth infrastructure is generated. This is fully backward-compatible.

Rate Limiting

The optional rateLimit object enables ASP.NET Core’s built-in sliding window rate limiter for the generated API.

{
  "config": {
    "rateLimit": {
      "permitLimit": 100,
      "windowSeconds": 60,
      "segmentsPerWindow": 6
    }
  }
}
Field Type Default Description
permitLimit integer 100 Maximum number of requests allowed within the time window.
windowSeconds integer 60 Duration of the time window in seconds.
segmentsPerWindow integer 6 Number of segments the window is divided into for smoother rate limiting.

When rate limiting is enabled:

When the rateLimit block is absent, no rate limiting infrastructure is generated. This is fully backward-compatible.

Versioning

The optional versioning object enables API versioning for all generated endpoints.

{
  "config": {
    "versioning": {
      "strategy": "UrlPath",
      "defaultVersion": 1,
      "prefix": "v",
      "headerName": "X-Api-Version"
    }
  }
}
Field Type Default Description
strategy string "UrlPath" Versioning strategy. UrlPath prepends version to routes (e.g., /v1/products). HeaderBased appends version to routes for header-based resolution.
defaultVersion integer 1 The default API version assigned to all generated endpoints.
prefix string "v" Version prefix string (e.g., "v" produces /v1/).
headerName string "X-Api-Version" Header name for header-based versioning (documentation only for UrlPath strategy).

When versioning is enabled:

Start with UrlPath strategy — it’s the most explicit and easiest to test. Routes clearly show which API version is being called. When the versioning block is absent, no versioning infrastructure is generated.

Entities

The entities object is a dictionary where each key is an entity name (PascalCase) and each value describes its properties and optional relationships and seed data.

{
  "entities": {
    "Product": {
      "properties": { ... },
      "relationships": { ... },
      "seedData": [ ... ]
    }
  }
}

Properties

Each property is defined by a name (PascalCase) mapped to an object with these fields:

Field Type Required Description
type string Yes The C# type of the property.
isKey boolean No Marks this property as the primary key. Exactly one property per entity should be a key.
required boolean No Generates a NotEmpty() validation rule.
maxLength integer No Generates a MaximumLength() validation rule.
minLength integer No Generates a MinimumLength() validation rule.
min integer No Generates a GreaterThanOrEqualTo() validation rule.
max integer No Generates a LessThanOrEqualTo() validation rule.
pattern string No Generates a Matches() validation rule with the given regex.

Supported Types

Type Aliases SQLite Mapping
Guid CHAR(36)
string String TEXT
int Int32 INTEGER
long Int64 INTEGER
float Single REAL
double Double REAL
decimal Decimal REAL
bool Boolean INTEGER
DateTime TEXT
DateTimeOffset TEXT
DateOnly TEXT
TimeOnly TEXT
byte[] BLOB

Type names are case-insensitive. string and String are equivalent, as are int and Int32.

Relationships

The optional relationships object on an entity defines associations with other entities.

{
  "Author": {
    "properties": {
      "Id": { "type": "Guid", "isKey": true },
      "Name": { "type": "string" }
    },
    "relationships": {
      "Posts": { "relatedEntity": "Post", "type": "OneToMany" }
    }
  }
}
Field Type Required Description
relatedEntity string Yes Name of the related entity (must exist in entities).
type string Yes Relationship type: OneToOne, OneToMany, ManyToMany, OneWay, ManyWay.

OneToMany relationships generate a nested GET endpoint (e.g., /authors/{authorId}/posts). See Generated Examples for sample output.

Enums

The optional top-level enums object defines C# enum types. Each key is the enum name, and the value is an array of string member names.

{
  "enums": {
    "Priority": ["Low", "Medium", "High", "Critical"],
    "Status": ["Draft", "Active", "Archived"]
  }
}

Each enum produces a separate .cs file under the Domain namespace. Enum-typed columns are mapped to INTEGER in the database.

You can use enum names as property types in your entities. For example, "type": "Priority" on a property will generate the correct C# type and an INTEGER database column.

Seed Data

Entities can include an optional seedData to populate tables with initial rows at startup. You can provide seed data either as an inline JSON array or as a path to a CSV file.

Inline JSON Array

{
  "Category": {
    "properties": {
      "Id": { "type": "Guid", "isKey": true },
      "Name": { "type": "string" },
      "IsActive": { "type": "bool" }
    },
    "seedData": [
      { "Id": "550e8400-e29b-41d4-a716-446655440001", "Name": "Electronics", "IsActive": true },
      { "Id": "550e8400-e29b-41d4-a716-446655440002", "Name": "Books", "IsActive": true }
    ]
  }
}

CSV File Reference

Instead of embedding rows in JSON, you can point to a CSV file. The path is relative to the ninjadog.json file location.

{
  "Category": {
    "properties": {
      "Id": { "type": "Guid", "isKey": true },
      "Name": { "type": "string" },
      "IsActive": { "type": "bool" }
    },
    "seedData": "data/categories.csv"
  }
}

Where data/categories.csv contains:

Id,Name,IsActive
550e8400-e29b-41d4-a716-446655440001,Electronics,true
550e8400-e29b-41d4-a716-446655440002,Books,true

The CSV file must have a header row with column names matching the entity property names. Values are automatically parsed as strings, integers, decimals, or booleans. Quoted fields (RFC 4180) are supported for values containing commas or quotes.

Each row must include the key property and any non-nullable properties. The generated DatabaseSeeder class runs INSERT statements at startup, immediately after DatabaseInitializer.InitializeAsync().

The DatabaseSeeder is only generated when at least one entity defines seedData. See Seed Data Generator for details on the generated code.

Native AOT Support

When features.aot is set to true, Ninjadog generates code optimized for Native AOT publishing:

{
  "config": {
    "features": {
      "aot": true
    }
  }
}

What changes with AOT enabled

Area Standard AOT
App builder WebApplication.CreateBuilder() WebApplication.CreateSlimBuilder()
JSON serialization Reflection-based Source-generated AppJsonSerializerContext
FastEndpoints Default config Configured with SerializerContext
Swagger / Client Gen Included Removed (incompatible with AOT)
Dapper Standard [DapperAot] attribute on repositories
NuGet packages Standard set Adds Dapper.AOT

Generated files

When AOT is enabled, an additional AppJsonSerializerContext.cs file is generated at the project root. It contains [JsonSerializable] attributes for every Request, Response, DTO, and Domain type, enabling System.Text.Json source generation.

Swagger UI and client code generation endpoints are not available when AOT is enabled, as they rely on runtime reflection. Use the standard (non-AOT) mode during development if you need these features.

To publish your AOT-enabled project, add <PublishAot>true</PublishAot> to your .csproj file and run dotnet publish -c Release.

Complete Example

A full ninjadog.json demonstrating all features:

{
  "$schema": "./ninjadog.schema.json",
  "config": {
    "name": "BookStore",
    "version": "1.0.0",
    "description": "Bookstore REST API",
    "rootNamespace": "BookStore.Api",
    "outputPath": "src/applications/BookStore",
    "saveGeneratedFiles": true,
    "cors": {
      "origins": ["https://bookstore.example.com"],
      "methods": ["GET", "POST", "PUT", "DELETE"],
      "headers": ["Content-Type", "Authorization"]
    },
    "features": {
      "softDelete": true,
      "auditing": true,
      "aot": false
    },
    "database": {
      "provider": "postgresql"
    },
    "auth": {
      "provider": "jwt",
      "issuer": "https://bookstore.example.com",
      "audience": "bookstore-api",
      "tokenExpirationMinutes": 120,
      "roles": ["Admin", "Editor"]
    },
    "rateLimit": {
      "permitLimit": 200,
      "windowSeconds": 60,
      "segmentsPerWindow": 6
    },
    "versioning": {
      "strategy": "UrlPath",
      "defaultVersion": 1,
      "prefix": "v"
    }
  },
  "enums": {
    "BookStatus": ["Draft", "Published", "OutOfPrint"],
    "Genre": ["Fiction", "NonFiction", "Science", "History"]
  },
  "entities": {
    "Author": {
      "properties": {
        "Id": { "type": "Guid", "isKey": true },
        "Name": { "type": "string", "required": true, "maxLength": 200, "minLength": 1 },
        "Email": { "type": "string", "pattern": "^[^@]+@[^@]+\\.[^@]+$" }
      },
      "relationships": {
        "Books": { "relatedEntity": "Book", "type": "OneToMany" }
      },
      "seedData": [
        { "Id": "a1b2c3d4-0000-0000-0000-000000000001", "Name": "Jane Austen", "Email": "jane@example.com" }
      ]
    },
    "Book": {
      "properties": {
        "Id": { "type": "Guid", "isKey": true },
        "Title": { "type": "string", "required": true, "maxLength": 500 },
        "Isbn": { "type": "string", "pattern": "^\\d{13}$" },
        "Price": { "type": "decimal", "min": 0, "max": 9999 },
        "Status": { "type": "BookStatus" },
        "Genre": { "type": "Genre" },
        "PublishedDate": { "type": "DateOnly" }
      },
      "seedData": [
        {
          "Id": "b1b2c3d4-0000-0000-0000-000000000001",
          "Title": "Pride and Prejudice",
          "Isbn": "9780141439518",
          "Price": 12.99,
          "Status": 1,
          "Genre": 0,
          "PublishedDate": "1813-01-28"
        }
      ]
    }
  }
}

Next Steps