Jebi.Rest
1.2.18
dotnet add package Jebi.Rest --version 1.2.18
NuGet\Install-Package Jebi.Rest -Version 1.2.18
<PackageReference Include="Jebi.Rest" Version="1.2.18" />
<PackageVersion Include="Jebi.Rest" Version="1.2.18" />
<PackageReference Include="Jebi.Rest" />
paket add Jebi.Rest --version 1.2.18
#r "nuget: Jebi.Rest, 1.2.18"
#:package Jebi.Rest@1.2.18
#addin nuget:?package=Jebi.Rest&version=1.2.18
#tool nuget:?package=Jebi.Rest&version=1.2.18
Jebi
Jebi stands for JSON Entity Binding Ingestion.
Jebi is a .NET library that maps JSON data onto a relational database, applying configurable transformation rules to bridge structural differences between source JSON and the target EF Core model.
Architecture
Jebi is split into two distinct layers.
Server (hosted service)
A single combined REST server exposes both the Catalog and Ingestion Plan surfaces.
- Project:
apps/Servers/Jebi.Catalog.IngestionPlan.Server.Rest - Role: Production server for Catalog + Plan REST API
Endpoints:
api/source/*for JSON schema managementapi/target/*for EF Core DbContext metadataapi/bindings/*for binding configurations and transformation rulesapi/plan/*for ingestion plan setup and key correlations
Client (NuGet package)
- Package:
Jebi.Rest - Description: Published NuGet package wiring
IJebiServiceagainst the remote server plus local execution engine
How It Works
Consumer App
└── IJebiService (from Jebi.Rest package)
├── Catalog calls ──→ HTTP → Jebi Server (api/source, api/target, api/bindings)
├── Plan calls ──→ HTTP → Jebi Server (api/plan)
└── Execute ──→ local → JebiIngestionDb + consumer's target DbContext(s)
The server holds all metadata (schemas, target models, binding rules, plans). Execution runs client-side against the consumer's own databases.
Target Model Contract
Jebi does not ask the user to manually configure target-side foreign-key semantics.
Target PK/FK semantics are derived from the consumer EF Core model
(DbContext + entity classes). This is an architectural rule:
- source-side mapping is user-configurable
- target-side relational semantics are model-derived
- target FK metadata is not considered user-authored configuration
This means the correctness of ingestion depends on the target DbContext
being modeled in a way that Jebi can inspect consistently.
Required DbContext modeling rules
When a target model is intended to be used by Jebi ingestion:
- every entity that participates in ingestion must expose an explicit CLR PK property
- every FK that ingestion may need to populate must expose an explicit CLR scalar FK property
- avoid shadow-only FK properties for ingestion-relevant relations
- navigation relationships must be discoverable by EF Core through
conventions,
[ForeignKey], or fluentHasForeignKey(...) - if a FK points to another ingested entity, its scalar FK property must represent the principal target PK, not an unrelated business field
- composite PK/FK models should be treated as advanced scenarios and modeled deliberately; the default path assumes single-key relations
Practical consequence
If a target property such as Utente.ContattoId is a FK to Contatto.IdContatto,
Jebi should infer that from the EF model. The user should bind a source field to
Utente.ContattoId, but the relational meaning of that target field comes from
the target model, not from manual configuration.
In the current runtime implementation, that source field should be the principal source key that participates in correlation registry resolution. Binding a target FK to an arbitrary non-key source scalar remains an advanced scenario and should not be assumed to resolve automatically.
Design guideline
If target relational semantics are wrong or missing, the fix belongs first in
the target EF model. Jebi may enrich or cache derived metadata, but it should
not replace the responsibility of the target DbContext to describe PK/FK
relationships clearly.
Infrastructure Projects
src/Catalog/Jebi.Catalog.Infrastructure: catalog persistence (source/target/binding)src/Ingestion/Jebi.Ingestion.Plan.Infrastructure: plan persistence (setup/key correlations/run results)src/Ingestion/Jebi.Ingestion.Execute.Infrastructure: runtime execution (EF provider/target integration)src/Shared/Jebi.Shared.Infrastructure: shared EF base components
The server requires two connection strings:
"ConnectionStrings": {
"JebiCatalogDb": "...",
"JebiPlanDb": "..."
}
Jebi Registration
REST (production)
builder.Services.AddJebiRest(
jebiExecutionDbConnectionString: "Data Source=jebi-execute.db",
authOptions: builder.Configuration.GetSection("Jebi:Auth").Get<JebiAuthOptions>()!,
ensureTargetDatabases: true,
typeof(MyTargetDbContext));
Jebi:Auth supports:
ClientId(required)ClientSecret(required)
For REST, auth/discovery endpoints are Jebi.Rest internal values.
Scope is fixed internally to jebi.api.
Runtime endpoints are fixed in package code (JebiRuntimeEndpoints):
http://localhost:5088/oauth2/tokenhttp://localhost:5088/.well-known/openid-configuration
Local (development/testing)
builder.Services.AddJebiLocal(
jebiCatalogConnectionString: "Data Source=catalog.db",
jebiExecutionDbConnectionString: "Data Source=plan.db",
ensureTargetDatabases: true,
typeof(MyTargetDbContext));
gRPC (production)
builder.Services.AddJebiGrpc(
jebiExecutionDbConnectionString: "Data Source=jebi-execute.db",
authOptions: builder.Configuration.GetSection("Jebi:Auth").Get<JebiAuthOptions>()!,
ensureTargetDatabases: true,
typeof(MyTargetDbContext));
For gRPC, transport/auth endpoints are Jebi.Grpc internal values.
Scope is fixed internally to jebi.api.
Runtime endpoints are fixed in package code (JebiRuntimeEndpoints):
http://localhost:5088/oauth2/tokenhttps://localhost:7065(Catalog/Plan gRPC)
For production deployment templates and endpoint matrix, see
docs/deployment/endpoints-and-config.md.
Subject-Scoped Persistence (Forward-Compatible)
Catalog and Plan persist a nullable shadow property SubjectId on
tenant-scoped entities, populated on write when claim sub is available.
TenantIdfilter remains always active.SubjectIdfilter is auto-enabled when a subject is available (override withEnableSubjectFilter).- Server tenancy can enforce subject presence for API/gRPC requests via
Jebi:Tenancy:RequireSubjectForApiRequests=true. - Schema updates are non-destructive: add
SubjectIdcolumn plus(TenantId, SubjectId)index. - Records with
SubjectId = nullremain shared within the tenant. - Architectural decision is formalized in
docs/adr/0001-subject-filter-auto-enable.md.
Facade Usage
var jebi = serviceProvider.GetRequiredService<IJebiService>();
var binding = await jebi.CreateBindingConfigurationAsync(new JebiCreateBindingConfigurationRequestDto
{
SourceSchemaName = "CustomerSchema",
TargetContextName = "MyTargetDbContext",
Name = "CustomerBinding"
});
await jebi.AddPropertyBindingRuleAsync(new JebiAddPropertyBindingRuleRequestDto
{
BindingConfigurationId = binding.BindingConfigurationId,
SourcePropertyName = "CustomerDef.customerId",
TargetPropertyFullyQualifiedName = "MyApp.Customer.CustomerId"
});
var result = await jebi.RunFromBindingAsync(new JebiRunFromBindingRequestDto
{
BindingConfigurationName = "CustomerBinding",
JsonPayload = jsonPayload,
Options = new JebiIngestionOptionsDto
{
ValidateSchema = true,
PersistRequested = true
}
});
Solution Filters
Work on a focused subset of the solution using the available filters:
dotnet build Jebi.Catalog.slnf
dotnet build Jebi.Ingestion.slnf
dotnet build Jebi.Packages.slnf
dotnet build Jebi.AppHost.slnf
Architecture Boundaries
Check project boundary rules:
bash scripts/ci/check-project-boundaries.sh
Validates that:
- consumer apps have
DisableTransitiveProjectReferences=true - Jebi surface packages do not expose internal projects as
compiledependencies
Also enforced in CI via the Architecture Boundaries workflow.
Docker
Pull and run the combined Catalog+Plan REST server:
docker pull ghcr.io/boffoli/jebi-catalog-ingestionplan-server-rest:latest
docker run -d -p 8080:8080 ghcr.io/boffoli/jebi-catalog-ingestionplan-server-rest:latest
Pull and run the web package demo (consumes Jebi.Rest as NuGet):
docker pull ghcr.io/boffoli/jebi-demo:latest
docker run -d -p 8081:8080 ghcr.io/boffoli/jebi-demo:latest
See docs/docker-demo-launchers.md
for ready-to-use launcher scripts.
| 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
- AutoMapper (>= 16.1.1)
- Grpc.Net.Client (>= 2.71.0)
- Humanizer.Core (>= 2.14.1)
- Jint (>= 4.2.2)
- JsonSchema.Net (>= 7.3.4)
- Newtonsoft.Json (>= 13.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.