Communication Layers and Protocols
mORMot provides a flexible Client-Server architecture supporting multiple communication protocols. This chapter covers the protocol options, class hierarchy, and configuration patterns.
┌─────────────────────────────────────────────────────────────────┐
│ Your Application │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────────────────────────────────────────────────┐
│ TRest (Abstract Parent) │
│ ├── Orm: IRestOrm (Object-Relational Mapping) │
│ ├── Services (Service-Oriented Architecture) │
│ └── Run: TRestRunThreads (Threading) │
└─────────────────────────────────────────────────────────────────┘
│ │
┌──────────────────────┐ ┌──────────────────────┐
│ TRestClient │ │ TRestServer │
│ (Client-side) │ │ (Server-side) │
└──────────────────────┘ └──────────────────────┘
│ │
┌─────────────────────────────────────────────────────────────────┐
│ Transport Layer │
│ ┌──────────┐ ┌─────────┐ ┌──────────┐ ┌────────────────┐ │
│ │In-Process│ │ HTTP │ │WebSockets│ │Named Pipes/Msg │ │
│ └──────────┘ └─────────┘ └──────────┘ └────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
| Protocol | Speed | Scaling | Hosting | Use Case |
|---|---|---|---|---|
| In-Process | ★★★★ | ★★★★ | Same process | Testing, embedded |
| HTTP | ★★ | ★★★★ | Remote | Production servers |
| WebSockets | ★★★ | ★★★ | Remote | Bidirectional callbacks |
| Named Pipes | ★★★ | ★ | Local | Windows services |
| Method | Best For | Considerations |
|---|---|---|
| SOA Interfaces | Public/private services | Recommended, full features |
| SOA Methods | Full REST control | More verbose |
| MVC Web | Dynamic websites | HTML-oriented |
| ORM REST | Testing, internal | Not for public APIs |
TRest (abstract)
└── TRestServer (abstract)
├── TRestServerDB → SQLite3 backend
├── TRestServerFullMemory → In-memory (no SQLite3)
└── TRestServerRemoteDB → Proxy to remote ORM
The primary server class with full SQLite3 database:
uses
mormot.orm.core,
mormot.rest.sqlite3;
var
Model: TOrmModel;
Server: TRestServerDB;
begin
Model := TOrmModel.Create([TOrmCustomer, TOrmOrder]);
Server := TRestServerDB.Create(Model, 'data.db3');
try
Server.CreateMissingTables;
// Server ready...
finally
Server.Free;
Model.Free;
end;
end;
Lightweight server without SQLite3 dependency:
uses
mormot.rest.memserver;
var
Server: TRestServerFullMemory;
begin
Server := TRestServerFullMemory.Create(Model);
try
// Fast in-memory storage
// Can persist to JSON/binary files
Server.StaticDataSaveToFile('backup.json');
finally
Server.Free;
end;
end;
Use cases:
Proxies ORM operations to another server:
uses
mormot.rest.core;
var
RemoteClient: TRestHttpClient;
ProxyServer: TRestServerRemoteDB;
begin
RemoteClient := TRestHttpClientWinHTTP.Create('dbserver', '8080', Model);
ProxyServer := TRestServerRemoteDB.Create(RemoteClient);
// ProxyServer forwards ORM to RemoteClient
end;
Use cases:
TRest (abstract)
└── TRestClientUri (abstract)
├── TRestClientDB → Direct SQLite3 access
├── TRestClientLibraryRequest → In-process DLL
└── TRestHttpClientGeneric → HTTP transport
├── TRestHttpClientWinSock → Raw sockets
├── TRestHttpClientWinHTTP → WinHTTP API (recommended)
├── TRestHttpClientWinINet → WinINet API
├── TRestHttpClientCurl → libcurl (cross-platform)
└── TRestHttpClientWebsockets → WebSocket upgrade
Direct access without network overhead:
uses
mormot.rest.sqlite3;
var
Client: TRestClientDB;
begin
// Creates internal TRestServerDB
Client := TRestClientDB.Create(Model, nil, 'data.db3', TRestServerDB);
try
Client.Orm.Add(Customer, True);
finally
Client.Free;
end;
end;
uses
mormot.rest.http.client;
var
Client: TRestHttpClientWinHTTP;
begin
// Recommended HTTP client for Windows
Client := TRestHttpClientWinHTTP.Create('localhost', '8080', Model);
try
if Client.SetUser('user', 'password') then
Client.Orm.Retrieve(123, Customer);
finally
Client.Free;
end;
end;
Client comparison:
| Class | Platform | HTTPS | Speed | Notes |
|---|---|---|---|---|
TRestHttpClientWinHTTP |
Windows | ✓ | Fast | Recommended |
TRestHttpClientWinINet |
Windows | ✓ | Medium | IE proxy integration |
TRestHttpClientWinSock |
Windows | ✗ | Fastest | No SSL |
TRestHttpClientCurl |
Cross-platform | ✓ | Fast | Requires libcurl |
For bidirectional communication:
uses
mormot.rest.http.client;
var
Client: TRestHttpClientWebsockets;
begin
Client := TRestHttpClientWebsockets.Create('localhost', '8080', Model);
try
// Upgrade to WebSocket
Client.WebSocketsUpgrade('');
// Now supports server-to-client callbacks
Client.Services.Resolve(IMyCallback, Callback);
finally
Client.Free;
end;
end;
Wraps TRestServer instances for HTTP access:
uses
mormot.rest.http.server;
var
HttpServer: TRestHttpServer;
begin
HttpServer := TRestHttpServer.Create(
'8080', // Port
[Server], // TRestServer instances
'+', // Domain ('+' = all)
useHttpAsync // Server mode
);
try
HttpServer.AccessControlAllowOrigin := '*'; // CORS
// Server running...
ReadLn;
finally
HttpServer.Free;
end;
end;
| Mode | Description | Use Case |
|---|---|---|
useHttpApi |
Windows HTTP.SYS (kernel-mode) | Windows production |
useHttpSocket |
Thread-per-connection | Behind reverse proxy |
useHttpAsync |
Event-driven async | Best scaling |
useBidirSocket |
WebSockets + threads | Callbacks (small scale) |
useBidirAsync |
WebSockets + async | Callbacks at scale |
// Production server (async, best performance)
HttpServer := TRestHttpServer.Create('8080', [Server], '+', useHttpAsync);
// WebSocket support
HttpServer := TRestHttpServer.Create('8080', [Server], '+', useBidirAsync);
// Enable TLS
HttpServer := TRestHttpServer.Create('443', [Server], '+',
useHttpAsync, nil, 0, secTLS);
// Self-signed certificate (development only)
HttpServer := TRestHttpServer.Create('443', [Server], '+',
useHttpAsync, nil, 0, secTLSSelfSigned);
For http.sys, certificates must be registered:
# Register certificate (Windows)
netsh http add sslcert ipport=0.0.0.0:443 certhash=<thumbprint> appid={<guid>}
One HTTP server can host multiple REST servers:
var
ApiServer, AdminServer: TRestServerDB;
begin
ApiServer := TRestServerDB.Create(ApiModel, 'api.db3');
ApiServer.Model.Root := 'api';
AdminServer := TRestServerDB.Create(AdminModel, 'admin.db3');
AdminServer.Model.Root := 'admin';
HttpServer := TRestHttpServer.Create('8080',
[ApiServer, AdminServer], '+', useHttpAsync);
// Access via:
// http://localhost:8080/api/...
// http://localhost:8080/admin/...
end;
Windows kernel-mode HTTP server provides:
http.sys requires URI registration (Administrator rights):
// Option 1: Auto-register (run as Admin once)
HttpServer := TRestHttpServer.Create('8080', [Server], '+',
useHttpApiRegisteringURI);
// Option 2: Manual registration
THttpApiServer.AddUrlAuthorize('api', '8080', False, '+');
Manual registration via netsh:
# List registered URLs
netsh http show urlacl
# Add URL reservation
netsh http add urlacl url=http://+:8080/api/ user=Everyone
# Delete URL reservation
netsh http delete urlacl url=http://+:8080/api/
# Open port in Windows Firewall
netsh advfirewall firewall add rule name="mORMot Server" ^
dir=in action=allow protocol=TCP localport=8080
TRestClientUri classes are thread-safe by design:
// Safe: URI() method is internally locked
procedure TWorkerThread.Execute;
begin
GlobalClient.Orm.Retrieve(ID, Record); // Thread-safe
end;
type
TRestServerAcquireMode = (
amUnlocked, // No locking (read-only operations)
amLocked, // Mutex protection (default for writes)
amBackgroundThread, // Queue to background thread
amMainThread // Queue to main thread (GUI)
);
// Configure execution modes
Server.AcquireWriteMode := amLocked;
Server.AcquireExecutionMode[execSoaByInterface] := amLocked;
| Context | Default Mode | Description |
|---|---|---|
execOrmGet |
amUnlocked |
ORM read operations |
execOrmWrite |
amLocked |
ORM write operations |
execSoaByMethod |
amUnlocked |
Method-based services |
execSoaByInterface |
amLocked |
Interface-based services |
var
Server: TRestServerDB;
HttpServer: TRestHttpServer;
begin
Server := TRestServerDB.Create(Model, 'data.db3');
// HTTP access
HttpServer := TRestHttpServer.Create('8080', [Server]);
// Same server accessible via HTTP and in-process
end;
┌─────────────────┐
│ Load Balancer │
│ (nginx/HAProxy)│
└────────┬────────┘
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ mORMot Srv 1│ │ mORMot Srv 2│ │ mORMot Srv 3│
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└─────────────────┼─────────────────┘
▼
┌─────────────────┐
│ Database │
│ (PostgreSQL) │
└─────────────────┘
Internet
│
┌───────┴───────┐
│ DMZ │ TRestServerRemoteDB (services only)
│ ┌─────────┐ │
│ │ Proxy │ │
│ │ Server │ │
│ └────┬────┘ │
└───────┼───────┘
│ (Internal network)
┌───────┴───────┐
│ Internal │ TRestServerDB (full ORM + services)
│ ┌─────────┐ │
│ │ Main │ │
│ │ Server │ │
│ └─────────┘ │
└───────────────┘
// CORRECT shutdown order
FreeAndNil(HttpServer); // 1. Stop accepting connections
FreeAndNil(Server); // 2. Free REST server
FreeAndNil(Model); // 3. Free model last
// WRONG - will cause access violations
FreeAndNil(Model); // Model freed while Server uses it!
FreeAndNil(Server);
FreeAndNil(HttpServer);
procedure GracefulShutdown;
begin
// Signal shutdown
HttpServer.Shutdown;
// Wait for pending requests (with timeout)
Sleep(1000);
// Free resources
FreeAndNil(HttpServer);
FreeAndNil(Server);
FreeAndNil(Model);
end;
| mORMot 1 | mORMot 2 |
|---|---|
TSQLRest |
TRest |
TSQLRestServer |
TRestServer |
TSQLRestServerDB |
TRestServerDB |
TSQLRestServerFullMemory |
TRestServerFullMemory |
TSQLRestClient |
TRestClient |
TSQLRestClientDB |
TRestClientDB |
TSQLHttpServer |
TRestHttpServer |
TSQLHttpClient |
TRestHttpClient |
| mORMot 1 | mORMot 2 |
|---|---|
mORMot.pas |
mormot.rest.core + mormot.orm.core |
mORMotSQLite3.pas |
mormot.rest.sqlite3 |
mORMotHttpServer.pas |
mormot.rest.http.server |
mORMotHttpClient.pas |
mormot.rest.http.client |
// mORMot 1: Direct ORM access on TRest
Server.Add(Customer, True);
// mORMot 2: Via Orm interface
Server.Orm.Add(Customer, True);
Next Chapter: Client-Server ORM Operations
| Previous | Index | Next |
|---|---|---|
| Chapter 10: JSON and RESTful Fundamentals | Index | Chapter 12: Client-Server ORM Operations |