BifrostQL.Core 0.4.398

There is a newer version of this package available.
See the version list below for details.
dotnet add package BifrostQL.Core --version 0.4.398
                    
NuGet\Install-Package BifrostQL.Core -Version 0.4.398
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BifrostQL.Core" Version="0.4.398" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BifrostQL.Core" Version="0.4.398" />
                    
Directory.Packages.props
<PackageReference Include="BifrostQL.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BifrostQL.Core --version 0.4.398
                    
#r "nuget: BifrostQL.Core, 0.4.398"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BifrostQL.Core@0.4.398
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BifrostQL.Core&version=0.4.398
                    
Install as a Cake Addin
#tool nuget:?package=BifrostQL.Core&version=0.4.398
                    
Install as a Cake Tool

BifrostQL

Zero-config GraphQL API for your existing database. One connection string. Full API.

Documentation | GitHub | NuGet

// Program.cs - that's it
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddBifrostQL(o => o.BindStandardConfig(builder.Configuration));
var app = builder.Build();
app.UseBifrostQL();
await app.RunAsync();
// appsettings.json
{
  "ConnectionStrings": {
    "bifrost": "Server=localhost;Database=mydb;User Id=sa;Password=xxx;TrustServerCertificate=True"
  },
  "BifrostQL": { "Path": "/graphql", "Playground": "/graphiql" }
}

That's a complete GraphQL API. Every table, every column, every relationship. Queries, mutations, filtering, pagination, joins -- all generated from your schema at startup.

What It Does

  • Reads your database schema, builds a GraphQL API. Add a table or column, restart, and the field appears with the correct type and validation. No code generation. No mapping files.
  • Solves the N+1 problem. BifrostQL generates one SQL query per table in the request, not one per row. All queries are sent in a single database round-trip and read back as multiple result sets. See How BifrostQL solves N+1 below.
  • Relationship fields. Foreign keys, matching key names, and many-to-many tables become nested GraphQL fields.
  • Directus-style filtering and pagination. Filter on any field with operators like _eq, _contains, _gt, _in. Pagination via limit/offset. Sorting via enum fields.
  • Full mutation support. Insert, update, upsert, delete, and batch mutations -- generated from primary key metadata. BifrostQL matches your input fields by name and does the right thing.

Supported Databases

Database Status Dialect
SQL Server Production BifrostQL.SqlServer
PostgreSQL Production BifrostQL.Ngsql
MySQL Production BifrostQL.MySql
SQLite Experimental BifrostQL.Sqlite

Module System

Cross-cutting concerns handled via metadata configuration. No custom code required for common patterns.

Tenant Isolation -- Automatic WHERE clause injection per query, keyed to the authenticated user's tenant ID. Queries physically cannot return another tenant's data.

"dbo.orders { tenant-filter: tenant_id }"

Soft Delete -- DELETE mutations become UPDATE mutations that set a timestamp. SELECT queries automatically exclude soft-deleted rows and expose _includeDeleted for administrative reads.

"dbo.orders { soft-delete: deleted_at; soft-delete-by: deleted_by_user_id }"

Audit Columns -- created_by, updated_by, created_on, updated_on populated automatically from the authenticated user context.

"dbo.*.createdOn { populate: created-on; update: none; }"
"dbo.*.updatedOn { populate: updated-on; update: none; }"

Visibility Control -- Hide system tables, internal columns, or entire schemas from the API.

"dbo.sys*, *.__* { visibility: hidden; }"

All module configuration uses a CSS-like selector syntax with glob patterns. Apply rules to one table, a pattern of tables, or every table in a schema.

Automatic Claim Filters -- Map arbitrary user-context claims to table columns for row-level security beyond a single tenant ID.

"dbo.orders { auto-filter: organization_id:org_id,region_id:region }"

Quick Start

Install

dotnet new web -n MyBifrostApi
cd MyBifrostApi
dotnet add package BifrostQL.Server
dotnet add package BifrostQL.SqlServer  # or BifrostQL.Ngsql, BifrostQL.MySql

Configure

Add your connection string and BifrostQL settings to appsettings.json:

{
  "ConnectionStrings": {
    "bifrost": "Server=localhost;Database=mydb;User Id=sa;Password=xxx;TrustServerCertificate=True"
  },
  "BifrostQL": {
    "Path": "/graphql",
    "Playground": "/graphiql",
    "DisableAuth": true,
    "Provider": "sqlserver"
  }
}

Wire Up

Replace your Program.cs:

using BifrostQL.Server;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddBifrostQL(o => o.BindStandardConfig(builder.Configuration));
builder.Services.AddCors();

var app = builder.Build();
app.UseCors(x => x.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin());
app.UseBifrostQL();
await app.RunAsync();

Run

dotnet run
# GraphQL playground at http://localhost:5000/graphiql
# API endpoint at http://localhost:5000/graphql

CLI Tool

BifrostQL includes a CLI tool for schema introspection, config generation, and local serving:

dotnet tool install -g BifrostQL.Tool
bifrost serve --connection "Server=localhost;Database=mydb;..."
bifrost schema --connection "..."
bifrost config-generate --connection "..."

Query Examples

# Get all users with pagination
{
  users(limit: 10, offset: 0, sort: [name_asc]) {
    data {
      userId
      name
      email
    }
  }
}

# Filter with operators
{
  orders(filter: { status: { _eq: "shipped" }, total: { _gt: 100 } }) {
    data {
      orderId
      total
      status
    }
  }
}

# Relationship fields - no config needed for matching keys
{
  orders {
    data {
      orderId
      customers {
        name
      }
    }
  }
}

# Insert mutation
mutation {
  products(insert: { name: "Widget", price: 9.99 })
}

How BifrostQL Solves N+1

Most GraphQL servers hit the database once per field resolver. A query that fetches 50 orders with their customers triggers 1 query for orders + 50 queries for customers -- the classic N+1 problem. DataLoader batching reduces this but still requires careful implementation per relationship.

BifrostQL takes a different approach: one query per table, regardless of row count.

When BifrostQL receives a GraphQL request, it:

  1. Parses the full query tree into a GqlObjectQuery structure before executing anything
  2. Generates one SQL statement per table referenced in the query. Joins use correlated subqueries to scope child rows to their parents.
  3. Sends all statements in a single database round-trip as a concatenated batch (SELECT ...; SELECT ...; SELECT ...)
  4. Reads all result sets from a single ExecuteReader call and assembles the response in memory

For example, this query:

{
  orders(limit: 50) {
    data {
      orderId
      total
      customers {
        name
        email
      }
      order_items {
        productId
        quantity
      }
    }
  }
}

Generates exactly 3 SQL queries -- one for orders, one for customers, one for order_items -- sent as a single batch. Not 50. Not 101. Three.

Approach Queries for 50 orders + customers + items
Naive resolvers 1 + 50 + 50 = 101
DataLoader batching 1 + 1 + 1 = 3 (but requires manual setup per relationship)
BifrostQL 3 (automatic, zero configuration)

This holds regardless of nesting depth. A four-level deep join across orders → customers → addresses → cities still produces exactly four queries in one round-trip.

Authentication

BifrostQL supports OAuth2/OIDC via JWT bearer tokens. When enabled, user context drives tenant isolation and audit column population.

{
  "JwtSettings": {
    "Authority": "https://your-idp.com",
    "Audience": "your-api"
  },
  "BifrostQL": {
    "DisableAuth": false
  }
}
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o => builder.Configuration.Bind("JwtSettings", o));

builder.Services.AddBifrostQL(o => o.BindStandardConfig(builder.Configuration));
var app = builder.Build();
app.UseAuthentication();
app.UseBifrostQL();
await app.RunAsync();

HTTP/3 Support

BifrostQL supports HTTP/3 (QUIC) with automatic HTTP/2 and HTTP/1.1 fallback:

{
  "BifrostQL": {
    "Http3": { "Enabled": true, "HttpsPort": 5001 }
  }
}
builder.UseBifrostHttp3();

Configuration Reference

Setting Description Default
ConnectionStrings:bifrost Database connection string Required
BifrostQL:Path GraphQL endpoint path /graphql
BifrostQL:Playground GraphiQL playground path /graphiql
BifrostQL:DisableAuth Disable authentication false
BifrostQL:Provider Database provider (sqlserver, postgres, mysql, sqlite) sqlserver
BifrostQL:Metadata Array of metadata configuration rules []

Metadata Rule Syntax

Rules use CSS-like selectors to target tables and columns:

"schema.table { property: value; }"     # Specific table
"schema.table.column { property: value; }"  # Specific column
"schema.* { property: value; }"          # All tables in schema
"schema.*|has(column) { property: value; }"  # Tables with a specific column
Property Values Description
tenant-filter column name Enable tenant isolation on this column
tenant-context-key claim key User-context key for tenant ID
auto-filter column:claim list Inject filters from user-context claims
auto-filter-bypass-role role name Role that bypasses auto filters
soft-delete column name Soft-delete timestamp column
soft-delete-by column name Column to record who deleted
delete-type soft Mark table for soft-delete behavior
populate created-by, updated-by, created-on, updated-on, deleted-on, deleted-by Auto-populate from user context
update none Mark column as read-only for updates
visibility hidden Hide from GraphQL schema
label column name Display label column for the table
auto-join true/false Enable automatic join inference
dynamic-joins true/false Emit _join / _single containers
default-limit number Default page size
de-pluralize true/false De-pluralize table names in schema
raw-sql enabled/disabled Expose guarded _rawQuery
generic-table enabled/disabled Expose guarded _table query
schema-prefix enabled/disabled Prefix table names with schema names
sp-include / sp-exclude regex Include or exclude stored procedures

Solution Structure

BifrostQL.sln
  src/
    BifrostQL.Core/          # Core library (net8.0, net9.0, net10.0)
    BifrostQL.Server/        # ASP.NET Core middleware
    BifrostQL.Host/          # Example host application
    BifrostQL.Tool/          # CLI tool (dotnet tool)
    BifrostQL.UI/            # Desktop app (Photino)
    data/
      BifrostQL.SqlServer/   # SQL Server dialect
      BifrostQL.Ngsql/       # PostgreSQL dialect
      BifrostQL.MySql/       # MySQL dialect
      BifrostQL.Sqlite/      # SQLite dialect
  tests/
    BifrostQL.Core.Test/
    BifrostQL.Server.Test/

Docker

docker build -t bifrostql .
docker run -e ConnectionStrings__bifrost="Server=host.docker.internal;..." -p 5000:80 bifrostql

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (5)

Showing the top 5 NuGet packages that depend on BifrostQL.Core:

Package Downloads
BifrostQL.Server

The fastest way to publish your SQL database as a GraphQL API.

BifrostQL.MySql

MySQL/MariaDB dialect support for BifrostQL.

BifrostQL.Sqlite

SQLite dialect support for BifrostQL.

BifrostQL.Ngsql

PostgreSQL dialect support for BifrostQL.

BifrostQL.SqlServer

SQL Server dialect support for BifrostQL.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.413 36 5/31/2026
0.4.412 39 5/30/2026
0.4.411 183 5/26/2026
0.4.410 188 5/25/2026
0.4.408 184 5/19/2026
0.4.407 194 5/19/2026
0.4.406 194 5/18/2026
0.4.405 178 5/18/2026
0.4.404 185 5/18/2026
0.4.403 188 5/18/2026
0.4.402 184 5/18/2026
0.4.401 189 5/18/2026
0.4.400 183 5/18/2026
0.4.399 189 5/18/2026
0.4.398 179 5/18/2026
0.4.397 180 5/18/2026
0.4.396 188 5/18/2026
0.4.395 181 5/18/2026
0.4.394 180 5/18/2026
0.4.393 181 5/18/2026
Loading failed