Delphi-spec-kit Dext Framework Patterns
Architectural patterns, Entity ORM, Minimal APIs and dependency injection for projects created with Dext Framework (cesarliws/dext).
git clone https://github.com/delphicleancode/delphi-spec-kit
T=$(mktemp -d) && git clone --depth=1 https://github.com/delphicleancode/delphi-spec-kit "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.claude/skills/dext-framework" ~/.claude/skills/delphicleancode-delphi-spec-kit-dext-framework-patterns && rm -rf "$T"
.claude/skills/dext-framework/SKILL.mdDext Framework Patterns (Delphi)
The Dext Framework is a complete ecosystem for Delphi, directly inspired by ASP.NET Core and Spring Boot. It is intended for high-performance corporate development. Unlike Horse or DMVC, Dext embraces Dependency Injection, Minimal APIs with automatic model binding and has its own Entity ORM (
Dext.Entity).
This manual provides the conventions that must be followed by the AI when coding with Dext.
Important Note: Dext Framework is not short for DevExpress/DevExtreme visual components, but rather the backend project (https://github.com/cesarliws/dext).
Core Principles
- Minimal Routing (Minimal APIs): Do not use traditional MVC Controllers unless necessary. Use functional routing syntax (
,MapGet
).MapPost - Auto Model Binding: Get JSON body not via strings and partial conversions, but by delegating strong typing to anonymous route parameters (
).function(Dto: MyDto): IResult - Integrated DI Container: All interface dependencies must be resolved via
(Injection). Do not use manual factories.App.Services - Smart ORM (Dext.Entity): Never concatenate SQL.
1. WebApp Lifecycle and DI
Bootstrap of a Dext API occurs by registering services in the same route pipeline.
program MyAPI; uses Dext.Web, Services.Interfaces, Services.Implementations; begin var App := WebApplication; var Builder := App.Builder; //1. Registration of Dependency Injection Services App.Services.AddSingleton<IEmailService, TEmailService>; App.Services.AddScoped<IOrderRepository, TOrderRepository>; //2. Route Mapping Builder.MapGet<IResult>('/health', function: IResult begin Result := Results.Ok('{"status": "ok"}'); end); //3. Start App.Run(8080); end.
2. Minimal APIs & Model Binding
The preferred way to build REST APIs with Dext is using typed anonymous delegates, with DI dependencies passed in the final arguments.
Create user (Post + DTO Body + Auth)
type TCreateUserDto = record Name: string; Age: Integer; end; //'Dto' is populated via JSON from the request body automatically. //'Database' is injected via DI. Builder.MapPost<TCreateUserDto, IDatabaseService, IResult>('/users', function(Dto: TCreateUserDto; Database: IDatabaseService): IResult begin if Dto.Name.IsEmpty then Exit(Results.BadRequest('Name is required')); Database.SaveUser(Dto.Name, Dto.Age); Result := Results.Created('/users/new', 'User Created'); end);
Path Params & Query
//Typed path-based routing (Route parameter Binding) Builder.MapGet<Integer, IResult>('/orders/{id}', function(Id: Integer): IResult begin var Order := FindOrder(Id); if Order = nil then Result := Results.NotFound else Result := Results.Ok(Order); end);
3. Dext.Entity (ORM & Smart Properties)
Database mapping with Dext is focused on strongly typed query building and "Code First" Classes.
LINQ-Like Queries
Avoid using complex RTTI or native ADOTables if you are on Dext. Deliver results in typed Collections (
IList<T>).
uses Dext.Entity; //P is the Smart Property representation for the context class var Products := DbContext.Products .Where((P.Price > 100) and (P.Stock > 0)) //'and' bitwise/Smart property syntax .OrderBy(P.Name) .Take(10) .ToList;
Understanding "Mass Update" via Dext.Entity
With Dext ORM, Updates can run in the database without pulling data into memory (as done in modern Entity Framework Core):
DbContext.Orders .Where(O.Status = 'Pending') .Update .Execute;
4. Returns (IResult)
Always return
IResult-based implementations on endpoints using the Results factory.
-> Status 200 + Automatically Serializes into JSON.Results.Ok( MeuRecord )
-> Status 201 + Header "Location".Results.Created('/rota', 'Msg')
-> Status 404.Results.NotFound
-> Status 400 bad request error.Results.BadRequest('Msg')
5. Dext.Net Async Tasks and Resilience (TAsyncTask)
Dext includes more modern promises/tasks primitives than the pure
TTask originals of Delphi.
uses Dext.Core.Tasks; //Use Task Flow from the central library TAsyncTask.Run<TUserProfile>( function: TUserProfile begin Result := ExternalService.Call(); end) .OnComplete( //Callback chamado no contexto Sincrono/Main thread. procedure(Profile: TUserProfile) begin ShowVclMessage(Profile.Name); end) .OnException( procedure(Ex: Exception) begin LogError(Ex.Message); end) .Start;
Review Checklist (Dext Framework)
- Fluent routes? Does the application use
/Builder.MapGet
with implicit binding instead of manual request manipulation and pure Body parse for complex json objects?MapPost - Has the DI container been powered? Are instances being passed to constructors/routers through
?App.Services - No Filter Strings in Data Modules? Did you use expressive Smart Properties (
) instead of query concat?.Where(E.Price > 100) - Are returns based on records and POLD objects? (Plain Old Delphi Objects, allowing UTF-8 Zero Allocation JSON from Dext).