You are not logged in.
I found this AI genetared useful:
https://zread.ai/synopse/mORMot2
and
https://zread.ai/synopse/mORMot
Hi AB.
I don't have problem with TBCD itself. Framework works correctly. My problem is in swagger.
I try my best not to waste your valuable time as much as possible. But in cases where I cannot solve the problem in any other way, I am forced to raise it here.
Hi.
I have interface based service:
function TestBcd(const Val: Tbcd): TServiceCustomAnswer;
it is shown in swagger like this:
{
"Val": {
"Precision": 0,
"SignSpecialPlaces": 0,
"Fraction": [
"string"
]
}
}
but I want swagger shows:
{
"Val": "string"
}
service method works when I pass parameter as string : "123456789.123456".
when I try to define this data type in template mustache file I got an error: (Parser error on line 623 duplicated mapping key)
"TBcd": {
"type": "string",
"description": "A string value that can be TBCD example : \"123456.123\""
}
Hi.
I want to remove some models from listing in swagger.
I can't find a method or anything to do this.
TOrmModel.Create([TjwtAuthUser, TAuthGroup,
TKEY_COLUMN_USAGE, TREFERENTIAL_CONSTRAINTS, TTABLES, TCOLUMNS], HttpRoot);for exmple I want to exclude TTABLES
Using batch, the speed is much better.
Thanks @ab
Wait. I made a mistake in my code.
After editing, it started working very quickly (less than a second).
My mistake was that I loaded the data in the restserver.create method, but I had set smOff and lmExclusive after the create method.
Thanks ![]()
I have external DB but I use sqlite3 for cache some data. There is no relation or mapping between sqlite and external db.
fPassakServer := TPassakRest.Create(MyModel, fDbConnection, False);
fPassakServer.DB.Synchronous := smOff;
fPassakServer.DB.LockingMode := lmExclusive;I don't feel a significant change in speed after the suggested changes.
Of course, I must say that the first time the data is added to the sqlite db it takes a long time, but the second time the server runs faster.
I am using sqlite because I want query chached data using sql.
I have rest server :
TPassakRest = class(TRestServerDB)
I add 2000 record using orm.
My hard drive is ssd.
this takes about 10 seconds to execute (slow):
LFileName := MakePath([Executable.ProgramFilePath, Executable.ProgramName + '.db']);
inherited Create(aModel, LFileName, aHandleUserAuthentication);but witout file name takes about 2 seconds:
inherited Create(aModel, aHandleUserAuthentication);starttransaction and commit does not help.
where is the problem.
I find it.
I override TRestServerAuthenticationHttpBasic.CheckPassword.
Now it works as expected.
Thank you so much
I understand what you mean. I can create users (or groups) and add them to the ORM:
var bb := TAuthUser.Create;
bb.PasswordPlain := '2';
bb.IDValue := 10;
bb.LogonName := 'admin1';
bb.GroupRights := TAuthGroup(1);
Self.Server.Add(bb, True);
Let me explain my real problem.
I have an existing database that my customers use. Passwords are hashed with my own method and stored in the database. I don't know what the passwords are because they are hashed and saved in my existing users table in my MySQL database.
How can I use my own hashing method to verify that a user's password is correct?
if I don't create TAuthgroup this work:
Result.GroupRights := TAuthGroup(1);
but when I call
Result.GroupRights.sessionTimeout := 100;
I got an AV.
mormot.rest.server.pas:
TOnAuthenticationUserRetrieve = function(Sender: TRestServerAuthentication;
Ctxt: TRestServerUriContext; aUserID: TID;
const aUserName: RawUtf8): TAuthUser of object;
TAuthUser defined in mormot.rest.core.pas :
TAuthUser = class(TOrm)
protected
fLogonName: RawUtf8;
fPasswordHashHexa: RawUtf8;
fDisplayName: RawUtf8;
fGroupRights: TAuthGroup;
fData: RawBlob;
procedure SetPasswordPlain(const Value: RawUtf8);
public
...
property GroupRights: TAuthGroup
read fGroupRights write fGroupRights;
so GroupRights is TAuthGroup class not id.
Hello,
I am having trouble with session timeouts in my REST server. I have set the SessionTimeout to 100, but the session still expires after 10 minutes.
Here is my OnAuthenticationUserRetrieve event handler:
fPassakServer.OnAuthenticationUserRetrieve := AuthenticationUserRetrieve;
function TfrmMain.AuthenticationUserRetrieve(Sender: TRestServerAuthentication; Ctxt: TRestServerUriContext; aUserID: TID; const aUserName: RawUtf8): TAuthUser;
begin
if ThreadSafeUsers.Exist(aUserName) then
begin
var User := ThreadSafeUsers.FindByLogonName(aUserName);
Result := TAuthUser.Create;
Result.LogonName := User.LogonName;
Result.PasswordPlain := User.PasswordPlain;
Result.IDValue := User.IDValue;
Result.GroupRights := User.GroupRights;
Result.GroupRights.SessionTimeout := 100;
end;end;
create TUser objects and store them in a thread-safe array named ThreadSafeUsers.FUsers.
A separate issue I have is with initializing the TAuthGroup. When I try to create it with AuthGroup := TAuthGroup.Create, I get an Access Violation (AV) error. However, using AuthGroup := TAuthGroup.CreateWithID(1) works fine.
I am struggling to understand how to properly create users and groups dynamically in this framework.
My auth service:
https://gist.github.com/a-nouri/46f6b58 … 694b30616d
I followed your suggestion:
function DeleteRecord(const ASql: RawUtf8; const Params: array of const; AConnection: TSqlDBConnection; out UpdateCount: Integer): TServiceCustomAnswer;
begin
try
UpdateCount := AConnection.Properties.ExecuteNoResult(ASql, Params);
if UpdateCount = 0 then
begin
Result.Status := HTTP_SERVERERROR;
Result.Content := TErrorDTO.CreateErrorJson('1' , 'no record found');
Exit;
end;
Result.Status := HTTP_SUCCESS;
Result.Content := TUtils.AddCommonHeaderToJSon('[]', true);
except
on E: EZSQLException do
begin
if EZSQLException(E).ErrorCode = 1451 then // foreign key constraint error
begin
Result.Status := HTTP_SERVERERROR;
Result.Content := TErrorDTO.CreateErrorJson('1' , 'record can not be deleted.');
end;
end;
end;
end;I created a custom exception class containing error codes and messages for handling business errors. However, one limitation I'm facing is that I cannot access URI parameters in this scenario.
True, but I wanted to raise errors in different places in the application if possible and handle them in only one place. This way, I would avoid writing hundreds of try excepts and centralize all error handling in one place.
there is no Uri. but there are Url = roort\CustomerService\Delete
Ctxt.Call^.InBody is unterminated json. {"cust_code"
error reurned from mysql server
Cannot delete or update a parent row: a foreign key constraint fails (`passak_utf`.`scm_sorder_cust_item`, CONSTRAINT `scm_sorder_cust_item_fk1` FOREIGN KEY (`sale_order`, `sorder_line_no`) REFERENCES `scm_sorder_det` (`sale_order`, `line_no`) ON UPDATE CASCADE)
Yes exactly
why it is not possible get url parameters in onError?
Ctxt.parameters is empty here
Somthing changed in mormot.soa.codegen.pas I think
I inslalled old version again.
I find why:
in prevoius version mORMotClient.json was:
{
"swagger": "2.0",
"info": {
"description": "Generated by PassakRestServer.exe (2025-10-28 18:42:15) using mORMot 2.3.10853 at 2025-10-29 11:46:42",
"title": "root API",
"version": ""
},
"host": "localhost:8282",
"basePath": "/root",
...
in new version :
"basePath": "/",
I don't know why this happen.
The REST server itself is working correctly. However, Swagger is generating the wrong URI. I didn't change even a single line of code after the upgrade.
This is the REST server code:
https://gist.github.com/a-nouri/d5347f8 … d1985736c5
swagger :
url -X 'POST' \
'http://192.168.1.12:8282/CustomerServic … stomerList' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{}'
Hi,
After updating mORMot2 to the latest version, Swagger is no longer working.
The URL format has changed.
Expected URL:
http://localhost:8282/root/Authentication/Login
Current URL:
http://localhost:8282/Authentication/Login
This is memory leak :
var
P: PByte;
begin
GetMem(P, 10);
fastmm report leak on shutdown:
1-12 bytes: Unknown x 1
how can I find location of memory leak?
madexcept shows line number and unit name. what about fastmm
Thakns.
Let me find where can I activate full debug mode for fastmm4.
Yes I used both madexcept and tsynlog.
I set global synlog setting:
var
LogFamily: TSynLogFamily;
....
LogFamily := SQLite3Log.Family;
LogFamily.Level := LOG_VERBOSE;
LogFamily.PerThreadLog := ptIdentifiedInOnFile;
but my rest server is restserverfullmemory.
without madexcept or urokalog how can I find memory leaks?
Hi everyone.
Madexcept report memory leak in this function:
I attached source and image of madexceptt report:
source:
https://gist.github.com/a-nouri/65937e5 … 248db87090
madexcept memory leak report:
https://passak.org/mormot/Untitled.png
Yes. You are right
Thanks
I know that
select CAST(code AS CHAR(10)) code,descr from table
solve the problem. but why there is difference between two functions?
Another problem
i have field in mysql like this
`code` varbinary(6)
ExecutePreparedAndFetchAllAsJson return this field as garbage character (MDAwMDAx). but
LJson := dbStmt.FetchAllToDocVariantArray();
TDocVariantData(LJson).ToJson return '000001' that it is correct!
hahahaha. it was easy!
thank you ![]()
Hi,
how can I serialize json in fast way (like mormot itself):
GetCustomerList is serialize with mormot and takes 650ms but my GetCustomerList2 takes 2100ms. 3 times slower.
https://gist.github.com/a-nouri/f0a0036 … 29ea86e345
where is my buttlenck.
I installed latest release and problem solved with ZeodLib 8.0.0 with mysql.
Hi.
Recently I swiched to ZeosLib 8.0.0 but I got error (Range Check Error) in:
ExecutePrepared function when calling :
var dbStmt := dbConn.Properties.ExecuteNoResult(sql, Params);
Seems it is ZeosLib error. But I'm not sure.
So I had to go back to ZeosLib 7.2
is it possible to bind parameter by name?
Lsql := 'select invoice_no,tran_date from fin_invoice where cust_code=:cust_code';
dbStmt := dbConn.NewStatementPrepared(LSql, True);
dbStmt.BindTextU(1, '1');
dbStmt.BindByName('cust_code') := '1';
Solved
Thank you.
I watched many videos on YouTube about authentication implementation with C#.
These videos showed an authentication service that allows Swagger users to obtain a JWT token and then click the Authorize button to import it as 'Bearer + JWT'.
I also created a similar service that is accessible in the Swagger section, which completely solved the problem.
Thank you and AB for your help.
Hi
serviceRunningContext^.Request.InBody is not valid json.
this is service method:
function TAuthenticationService.Login(const UserName, Password: RawUTF8): RawJson;
begin
var a := serviceRunningContext^.Request;
var b := TPassakRest(Server).fRestServerAuthentication;
TRestServerAuthenticationJWT(b).Auth(a);
end;body json is:
{
"UserName": "Admin",
"Password": "synopse"
}
serviceRunningContext^.Request.InBody is
{"UserName: "Admin "Password: "synopse
First of all, I put the Swagger.json.mustache file in a "templates" folder next to my REST server executable.
I don't remember where I found the Swagger.json.mustache file and copied it there.
Then, I added this line to my REST server startup procedure:
AddToServerWrapperMethod(MyRestServer,['templates','templates']);
After this step, the URL "http://localhost:8282/root/wrapper/" shows some links and information for me, including the mORMotClient.json file.
I shared my template file here:
https://gist.github.com/a-nouri/6bf970a … dac0a15c8a
I'm new to this and it took me several days to do this simple thing. I need to go back and study more on this. ![]()
thank you!
Finally, I found out how to add the Authorize button to my Swagger template.
I added this to the Swagger.json.mustache file, something like this:
"securityDefinitions": {
"JWTAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header",
"description": "Enter your JWT token here. Example: Bearer eyJhbGciOiJIUzI1NiIs..."
}
},
"security": [
{
"JWTAuth": []
}
],
Then, I get the JWT token in the Delphi REST debugger or Postman and put it in the Authorization field as:
Bearer eyJhbGciOiJIUzI1...
The difficulty here is that it requires getting the JWT from the REST debugger and pasting it in. I can't find a way to supply the username and password directly on the Swagger page to get the JWT and automate this process.
By the way, this is a big step forward for me.
I learned how to create HTML for displaying Swagger:
html := '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="SwaggerUI" />
<title>SwaggerUI</title>
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui.css" />
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://unpkg.com/swagger-ui-dist@5.11.0/swagger-ui-bundle.js" crossorigin></script>
<script>
window.onload = () => {
window.ui = SwaggerUIBundle({
url: '../wrapper/Swagger/mORMotClient.json',
dom_id: '#swagger-ui',
});
};
</script>
</body>
</html>
''';
Done!
Hi everyone!
I am using react as front end.
Is there a way to create json without \uFFF0 char?
mormot documentation:
// - BLOB field value is saved as Base64, in the '"\uFFF0base64encodedbinary"'
// format and contains true BLOB data
procedure ExecutePreparedAndFetchAllAsJson(Expanded: boolean;
out Json: RawUtf8; ReturnedRowCount: PPtrInt = nil);
Thank you
Hi every one.
//var LItemService := aPassakServer.ServiceRegister(TItemService, [TypeInfo(IItemService)], sicPerSession, '4');
var LItemService := aPassakServer.ServiceDefine(TItemService, [IItemService], sicPerSession, '4');
LItemService.ResultAsJsonObjectWithoutResult := True;
LItemService.ByPassAuthentication := False; //We can bypass authenticationwhen I cnahge ServiceRegister to ServiceDefine. ResultAsJsonObjectWithoutResult does not affect and result is:
{
"result": {
"Result": [
{
"cust_code": "0001",
"type": "domestic"
}
}
}
expected result is:
{
"Result": [
{
"cust_code": "0001",
"type": "domestic"
}
}
your gist link is not public.
Sending http://localhost:8282/root/CacheFlush/_ping_ does not renew session!
server start:
https://gist.github.com/a-nouri/48c5806 … 5947366ccd
I debbug it and in:
function TServiceFactoryServer.RenewSession(Ctxt: TRestServerUriContext): integer;
fInstances.Count is 0 !
and fInstanceCreation is sicShared
so function exit.
I don't know why fInstances.Count is zero, but why does this function only work for sicClientDriven, sicPerSession.
Thanks for help
There is no property in mormot cookie for expires. Is this correct way?
procedure TRestServerAuthenticationJWT.SessionCreate(Ctxt: TRestServerUriContext; var User: TAuthUser);
begin
//...
var ExpireStr: RawUtf8;
var ExpireTime := Now + 1;
ExpireStr := DateTimeToHttpDate(ExpireTime);
Ctxt.OutSetCookie := 'JWT=' + Token + '; Expires=' + ExpireStr;
end;I implemented my client and server using your github code, but there are memory leak in internalrequest!
I am using method 2. but I don't undrestand "don't publish the tables as REST"