Deepsea 1.0.0-preview.3
dotnet add package Deepsea --version 1.0.0-preview.3
NuGet\Install-Package Deepsea -Version 1.0.0-preview.3
<PackageReference Include="Deepsea" Version="1.0.0-preview.3" />
<PackageVersion Include="Deepsea" Version="1.0.0-preview.3" />
<PackageReference Include="Deepsea" />
paket add Deepsea --version 1.0.0-preview.3
#r "nuget: Deepsea, 1.0.0-preview.3"
#:package Deepsea@1.0.0-preview.3
#addin nuget:?package=Deepsea&version=1.0.0-preview.3&prerelease
#tool nuget:?package=Deepsea&version=1.0.0-preview.3&prerelease
🌊 Deepsea - A lightweight, GraphQL-feel, JSON-native query language.
🚧 Note: Deepsea is in preview - APIs may change. Will be open-sourced at https://github.com/hoangitk/deepsea once stable.
🌐 Language: English | Tiếng Việt
Deepsea is a lightweight, GraphQL-feel, JSON-native query language.
Ever wanted the GraphQL-feel without learning a new DSL? Deepsea is that answer - a query language built on the JSON you already know. Clients build queries with native objects: no template strings, easy to diff, lint, and cache.
Design Goals
Deepsea is designed around simplicity and easy integration:
- JSON-first: every query is a valid JSON object.
- No extra DSL surface for clients: queries can be built directly with native objects.
- Clear data shape: results follow the requested projection.
- Pipeline-based extensibility: middleware, directives, and batching work together.
- Early error reporting: schema and query errors are detected before runtime invocation.
Zero-Ceremony Schema
Deepsea works directly with your existing code - no DTOs, no schema files, no boilerplate resolvers.
// Your existing domain model - no changes needed
public record Movie(int Id, string Title, int Year);
public record Actor(int Id, string Name);
// Your existing service - no attributes needed
public class MovieService
{
public async Task<Movie> ById(int id) => ...;
public async Task<IEnumerable<Movie>> Search(Filter filter) => ...;
}
// One line to expose everything
var schema = new DeepseaSchema();
// Default convention: class name -> prefix
schema.Register<MovieService>(); // -> movieService.byId, movieService.search
// Custom prefix for cleaner paths
schema.Register<MovieService>("movie"); // -> movie.byId, movie.search
// Batch -> movie.actors
schema.Register<Movie>(
"actors",
(IEnumerable<Movie> movies, Db db) => //Dictionary<Movie, Actor[]>,
DeepseaMemberType.Batch);
// Nested types (Movie, Actor) are auto-discovered - no registration needed
Core Query Model
Deepsea keeps a small, memorable model:
- Use
()to pass arguments. - Use regular object keys for field projection.
- Use
=>to alias, unnest. - Use path keys like
movie.byIdfor root member calls. - Use
@-prefixed keys for directives. - Use
$-prefixed keys for variables.
{
"movie.byId": {
"()": { "id": "$id" }
"title": true,
"actors": {
"name=>": true
},
},
}
Key Features
- Projection & alias:
"title => ten": true,"gender=>": { ... }(unnest). - Batch execution: resolvers can accept
IEnumerable<T>to reduce N+1 queries. - Directive pipeline: control, transform, and metadata directive groups.
- Middleware pipeline: apply auth, caching, logging, and cross-cutting concerns.
- Variables:
$vartokens resolved fromctx.Variables. - Union & fragments: supports
__typenameand fragment-style projections. - Partial results: failed fields collect errors while successful fields still return.
- Parallel execution: same-level fields can run concurrently with
MaxParallelTasks.
Architecture
Deepsea separates responsibilities into three layers:
| Layer | Role |
|---|---|
| Schema | Register types, members, directives |
| Planner | Parse, validate, and build the execution plan tree |
| Executor | Traverse plan nodes, invoke resolvers, shape output |
This architecture makes testing easier, execution safer, and leaves room for optimization.
Quick Start
dotnet add package Deepsea
// 1. Declare the schema
var schema = new DeepseaSchema();
schema.Register(typeof(MovieService));
// 2. Create the runtime
var runtime = new DeepseaRuntime(schema);
// 3. Execute a query
var result = await runtime.ExecuteAsync(new DeepseaRequest
{
Query = JsonNode.Parse("""
{
"movie.byId": {
"()": { "id": "$id" },
"title": true
}
}
"""),
Variables = new DeepseaVariables { ["id"] = 1 }
});
Console.WriteLine(result.Data);
ASP.NET Core Integration
Deepsea integrates seamlessly with ASP.NET Core via minimal APIs:
var builder = WebApplication.CreateBuilder(args);
// Register Deepsea services
builder.Services.AddDeepsea(cfg =>
{
cfg.Assemblies = [typeof(MovieService).Assembly];
cfg.ServiceLifetime = ServiceLifetime.Scoped;
});
var app = builder.Build();
// Expose the query endpoint
app.MapPost("/api/deepsea", static async (
DeepseaRequest request,
DeepseaRuntime runtime,
CancellationToken cancellationToken) =>
{
runtime
.RegisterBuiltInDirectives()
.UseGlobalMiddlewares()
;
var result = await runtime.ExecuteAsync(request, cancellationToken);
return Results.Ok(result);
});
await app.RunAsync();
- Query the endpoint
curl -X POST http://localhost:5000/api/deepsea \
-H "Content-Type: application/json" \
-d '{
"query": {
"movie.byId": {
"()": { "id": 1 },
"id": true,
"title": true,
"authors": {
"name": "@upper"
},
"actors": {
"name=>": true
}
}
}
}'
- Response
{
"data": {
"movie.byId": {
"id": 1,
"title": "Phàm Nhân Tu Tiên",
"authors": [
{
"name": "VONG NGỮ"
}
],
"actors": ["Hàn Lập", "Nam Cung Uyển"]
}
},
"errors": []
}
Full Example
// query
{
"movie": {
"search": {
"()": { "filter": "$filter" },
"id": true,
"title": true,
"authors": {
"name": "@upper"
},
"actors": {
"name=>": true
}
},
"count": {
"()": { "filter": "$filter" }
}
}
}
// variables
{ "filter": { "title": "Phàm Nhân" } }
The result matches the requested shape; directives apply through the pipeline, variables resolve from context, and nested fields stay batch-friendly.
For example, the result could be:
{
"movie": {
"search": [
{
"id": 1,
"title": "Phàm Nhân Tu Tiên",
"authors": [
{
"name": "VONG NGỮ"
}
],
"actors": ["Hàn Lập", "Nam Cung Uyển"]
}
],
"count": 1
}
}
Note: actors is an array of scalars because name=> unnested each actor's name out of its object.
Roadmap
Deepsea is actively evolving into a complete query framework. Here's what's coming:
Phase 1: Core Foundation ✅
- JSON-native query language
- Schema auto-discovery
- Batch execution (N+1 prevention)
- Middleware & directives
- ASP.NET Core integration
Phase 2: Production Ready 🚧 (middleware-powered)
- Query Caching: response caching with TTL via middleware
- Rate Limiting: per-client query complexity limits
- Audit Logging: track all queries with user context
- Performance Monitoring: query tracing, slow-query alerts
- Authorization hooks: bring your own policy
- Health Checks: ASP.NET Core health check integration
- Production Features: DataMask directive
Phase 3: DX 📋
- Deepsea Playground: interactive query editor with auto-complete
- Schema Explorer: visual schema browser with type docs
- Query Analyzer: visualize execution plan and cost
Phase 4: Advanced Features 🔮
- Subscriptions: real-time streaming via WebSocket
- Schema Federation: merge deepsea endpoint into one graph
- Code Generation: generate TS/C# clients from schema
- Source Generator: AOT-friendly
Community & Ecosystem
- How-to wiki
- Entity Framework Core integration: auto-discover
DbSets for search, count, pagination, and CRUD out of the box - GraphQL gateway (bridge Deepsea services to GraphQL clients)
Inspiration
Deepsea draws inspiration from:
- deeprjs for query syntax.
- graphql-aspnet for Batch Extension and simplified schema declaration.
License
MIT - free to use, modify, and distribute.
Contributing
PRs welcome! See CONTRIBUTING.md for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-preview.3 | 75 | 8/14/2026 |
| 1.0.0-preview.2 | 73 | 8/13/2026 |
| 1.0.0-preview.1 | 73 | 8/12/2026 |
- Union types support
- .editorconfig