Skip to content

The Dext Journey: Evolving High Performance in Delphi Backend

Dext v1 RC

Enterprise systems development demands constant evolution. At Project Dext, our goal has never been just to deliver a finished product, but to build a solid, modern, and high-performance foundation for the Delphi community. Today, we share another fundamental evolution: the Release Candidate 1.0 stage.

This update consolidates months of refinement in the framework engine, bringing features that once seemed distant from the Object Pascal ecosystem.


✨ Key Features: The Final Evolution Before v1.0

Section titled “✨ Key Features: The Final Evolution Before v1.0”

We have drastically simplified data exposure and complex query execution, bringing the ORM to an unprecedented level of expressiveness.

The functionality to generate automatic endpoints (“Database as API”) has received a significant upgrade in its integration. Now, with MapDataApi, you register a complete and secure CRUD directly in the application builder, with native support for dependency injection and access policies.

// A single line to securely expose your entity
App.Builder.MapDataApi<TProduct>('/api/v1/products',
DataApiOptions.RequireAuth.AllowReadWrite
);

Database as API

🔍 Dynamic Specification Mapping: Your Client in Control

Section titled “🔍 Dynamic Specification Mapping: Your Client in Control”

Natively integrated into Database as API, QueryString filtering allows your API client to build complex queries without you writing a single line of backend logic. Dext maps intelligent suffixes directly to SQL.

Examples of powerful URLs:

  • GET /api/v1/products?price_gt=100&stock_lt=10 -> Filters price > 100 and stock < 10.
  • GET /api/v1/products?name_cont=Dext&_sort=id desc -> Searches for names containing “Dext” with descending sort.
  • GET /api/v1/products?category_in=1,2,5 -> Filters by multiple values simultaneously.

This transforms your API into a flexible tool, reducing the need to create multiple search methods for each combination of filters.

🔗 Multi-Mapping ([Nested]): The “Dapper” of Delphi

Section titled “🔗 Multi-Mapping ([Nested]): The “Dapper” of Delphi”

We have implemented native support for Multi-Mapping inspired by Dapper. Using the [Nested] attribute, Dext can hydrate complex object graphs from a single SQL query with joins.

Imagine loading a TOrder that has a TCustomer, which in turn has a TAddress. In Dext, this is done recursively and performantly, mapping the class hierarchy in a single trip to the database.

var OrderProxy := Prototype.Entity<TOrder>;
var Orders := Db.Orders
.Include(OrderProxy.Customer) // Eager loading via Proxy
.ThenInclude(OrderProxy.Customer.Address)
.ToList;

Multi-Mapping

🔒 Pessimistic Locking: Total Concurrency Control

Section titled “🔒 Pessimistic Locking: Total Concurrency Control”

Concurrency control is now native in the fluent API. You can request database-level locks for critical transactions directly in the query:

var Product := Db.Products
.Where(Prop('Id') = 1)
.Lock(TLockMode.Update) // Generates FOR UPDATE (PostgreSQL) or UPDLOCK (SQL Server)
.FirstOrDefault;

🛠️ Stored Procedures & Views: First-Class Citizens

Section titled “🛠️ Stored Procedures & Views: First-Class Citizens”

We know that the real world requires using complex logic that resides in the database. Dext has drastically simplified interaction with Stored Procedures and Views.

  • Views: Map complex Views exactly like tables, taking full advantage of automatic hydration.
  • Stored Procedures: Declarative mapping using attributes, with support for input and output parameters and various return types.
type
[StoredProcedure('GetEmployeeSalary')]
TEmployeeSalaryDTO = class
private
FEmpId: Integer;
FSalary: Double;
FBonus: Double;
public
[DbParam(ptInput)]
property EmpId: Integer read FEmpId write FEmpId;
[DbParam(ptOutput)]
property Salary: Double read FSalary write FSalary;
[DbParam(ptOutput, 'p_bonus')]
property Bonus: Double read FBonus write FBonus;
end;

This ensures that you can use advanced database features like SQL Server and PostgreSQL without sacrificing strong typing and the elegance of your Pascal code.


The refactoring of the Interception engine (Proxying) to the Core brought something revolutionary: the ability to manage states without polluting your class fields. This is what we call Shadow Fields and Anonymous States.

This allows you to have data persisted in the database (such as TenantId, AuditLog, or Foreign Keys) that your domain code doesn’t even see. The class remains a pure POCO (Plain Old CLR Object), while the ORM manages metadata “in the shadows”.

Practical Example: Tenant Isolation without polluting the Domain Your domain class doesn’t need to know that the Database requires a TenantId on every line:

[Table('Products')]
TProduct = class
public
[PK, AutoInc] property Id: Integer ...
property Name: string ...
// Note: NO TenantId field here!
end;

Fluent Mapping (Shadow Property):

ModelBuilder.Entity<TProduct>
.ShadowProperty('TenantId') // Ghost property!
.HasColumnName('tenant_id');

What Dext does in the Database:

SELECT Id, Name, tenant_id FROM Products WHERE tenant_id = :current_tenant

How to access the Shadow Field if needed? You can read or write these values via the Entry API:

var TenantId := Db.Entry(Product).Member('TenantId').GetCurrentValue.AsInteger;

This brings functionality similar to Anonymous Objects or Dynamic Properties of modern frameworks to Delphi, allowing clean architectures where the Database doesn’t dictate your class design.


🚀 Web & Performance: Zero-Allocation Streaming

Section titled “🚀 Web & Performance: Zero-Allocation Streaming”

The web framework now uses TUtf8JsonWriter for the Database as API engine.

  • Data is written using direct streaming from the database to the socket.
  • Zero-Allocation: There are almost no temporary string allocations, which drastically reduces pressure on the Garbage Collector (or Heap fragmentation in Delphi) and massively increases throughput.

To demonstrate Dext’s power in real-world scenarios, we’ve created a new series of examples focused on simplified Domain-Driven Design (DDD) and Unit Testing. These projects show how Dext seamlessly integrates into clean, decoupled architectures.

The new examples explore separation of concerns, using Dext to manage persistence without it dictating business rules:

  • Web.SalesSystem & Web.FoodDelivery: Demonstrate the use of Services, Repositories, and Domain Entities with rich validations integrated into the ORM lifecycle.
  • Web.TicketSales: Focused on high concurrency and the use of Pessimistic Locking to ensure integrity in ticket sales.
  • Web.HelpDesk: A complete ticket system that uses the Database as API engine to speed up the frontend while maintaining custom logic where needed.

All these examples come with Unit and Integration Testing suites. We show how Dext facilitates mocking and the creation of isolated testing environments, ensuring your database logic is testable and reliable.

  • MultiTenancy: Technical demonstration of isolation via Schema (PostgreSQL) and via Database with dynamic connection switching.
  • SmartPropsDemo: Advanced use of Prop<T> and Nullable<T> for transparent persistence and full change control (Dirty Tracking).
  • SQL Generator: Improved DDL generation, ignoring navigation properties in CREATE TABLE.
  • TActivator: Intelligent constructor prioritization for derived classes.
  • Lazy Loading: Fixed Access Violations in circular relationship proxies.

The work doesn’t stop. We’ve already started a deep refactor of Dext.Collections. Our goal is to completely eliminate dependency on Delphi’s default generics, attacking “code bloat” and raising performance to a new level of excellence.

Dext Collections Mystery

Evolution is constant. Dext is just beginning.