#1 2024-06-24 08:51:57

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Where do I start?

Hi,
The main point I'd like to make is that there is no documentation or guide for learning the basics of this framework.
There are only references from the website to GitHub and back again. In the end, you can only look at the sample programs!
It's very frustrating that there is no explanation of how to work with this framework from the ground up.

Offline

#2 2024-06-24 10:42:44

flydev
Member
From: France
Registered: 2020-11-27
Posts: 73
Website

Re: Where do I start?

Hi, I can understand your point of view but some statements are false like about the documentation, at contrario the doc is quite gigantic and can be complex on the first read - but once you get a bit familiar with the framework structure and conventions, the doc turn easy to understand and will became your handbook, and it's still also true if we take into account that the current full documentation is about the version 1.

From the ground up, I can only suggest to read the whole introduction which include chapter 1, 2 and 3 - then play without getting into details with the samples, I mean compile, test and then read the code, then going from code to the documentation to make some corelation, also, the whole source code contain detailled comments.

You can find also Thomas (tbo)'s tutorials (read the readme linked on github), and to be honest, the full samples from the v1 are still useful.

Some links:
- doc v1 (v2 is a wip)
- Thomas tutorials (you will find write up, translatable, on delphipraxis)
- Stephan Bester's intros on Medium
- Again, some tutorials based on the v1, but still applies!
- A lot of samples there

The learning curve is rude, but definitely worth it.

Online

#3 2024-06-24 15:58:38

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

Yes, the links in the first paragraph of the README in the repository do apply.

https://github.com/synopse/mORMot2?tab= … #resources

Offline

#4 2024-06-25 10:43:55

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Thanks for your guidance, friends.

I know enough to build a simple server and use a websocket with it.
I'm looking for the basic concepts and principles to have a good understanding of its structure in order to create a large system.
I've already written five large APIs with Horse. Recently, a friend of mine mentioned that mormot v2 has changed a lot. It is very fast. That's why I decided to write the new API with mormot. But I have a superficial understanding of it. I would like to know how to get the most out of it.

Offline

#5 2024-06-25 11:50:43

flydev
Member
From: France
Registered: 2020-11-27
Posts: 73
Website

Re: Where do I start?

Just keep in mind what's already said as you will need these references, then read New Async HTTP/WebSocket Server blog post to get a better overview and then run/study the code of the program used for the techempower benchmark which is IMO the best starting point as it show almost all of what you will need for your endpoints, without complexity.

Just grab the project, uncomment USE_SQLITE3, compile and test urls with Postman, browser or favorite tool.

Online

#6 2024-06-25 11:51:09

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

Horse is nice, for a basic server-side API.
It claims to be fast: I don't see why it should be especially fast in respect to alternatives, because it is based on other web servers (it does not have its own web server).
Perhaps it is faster than Datasnap, but it is not difficult. wink
It could be a good idea to include Horse in the TFB benchmark, for instance, and compare with mORMot (and its own async web server) which ended in rank #12 against the most tuned proof of concepts of other languages:
https://www.techempower.com/benchmarks/ … =composite
To be fair, a REST API is just one brick of server-side process.

For a large API with mORMot, the easiest and most maintainable is to use interface-based-services, with several interfaces, and dedicated methods.
Using interfaces is IMHO the cleanest way to define an API, and follow strong coding principles like SOLID.
Over websockets, you can have real time response from the clients to the server, with minimal coding.
Another advantage is to have ready-to-use Delphi/FPC clients using RTTI, or abilities to generate client code or documentation.
And it is still a regular API using standard JSON + HTTP(S) to communicate.

I understand your scepticism against mORMot size and learn curve.
It is closed to WCF interfaces defined in strong-typed C#, than JavaScript-like frameworks.
We still plan to make some high-level wrapper about mORMot classes, to get quickly started.

Offline

#7 2024-06-27 08:05:24

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Thank you for your responses, friends.

I understand that there are three ways to work with mORMot:
1 - The REST ORM
2 - Methods-based services
3 - Interface-based services

I also didn't understand how to create multiple routes for my API. What I did was look for the route name in the URL in the OnRequest event and execute a function.

I also tried to use the route and router properties in the following way, but it didn't work:
fHttpServer.Rout.Get('Ping',Ping);
fHttpServer.Router.Get('Ping',Ping);

Last edited by Kabiri (2024-06-27 08:07:04)

Offline

#8 2024-06-27 08:14:32

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

As I wrote, I would advice using  Interface-based services for any project with a growing number of endpoints.

Then you can make some routing in front of it, using built-in URI redirection from the outer route to the interface-based-service standard route, as generated by the RTTI.
https://blog.synopse.info/?post/2022/12 … -Christmas
Look at "Internal URI rewrite" in this blog article.
You can just set a RawUtf8 destination URI instead of a method callback.

Offline

#9 2024-06-29 13:03:52

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Based on what I have learned, I wanted to create an interface-based server.
I do not want to use ORM on my server. That's why I did not create a class for orm and data.
The program stops with an error and I don't understand why.

---I have removed the code to comply with the rules.

Last edited by Kabiri (2024-06-30 17:53:12)

Offline

#10 2024-06-29 17:46:39

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

Hello,

1) Please follow the forum rules and don't put code in the messages directly.

2) You are using TServerRest which is NOT to be used as such: this is an abstract class.
Use TRestServerFullMemory instead, as documented:

  // Update() Delete() methods - so if you want a REST server with no ORM
  // (e.g. for a pure SOA server), use (or inherit) TRestServerFullMemory

Offline

#11 2024-06-30 17:58:31

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Thank you.
I have created a new record for the output, but the JSON output contains both the input record and the record I defined for the output. What can I do to prevent the input from being sent in the output?
Also, how can I test this with Postman?
I tried several URLs in my Postman request, but the inputs are not being received.

get : http://127.0.0.1:8080/api/Calculator.Add/?Data={N1:1,N2:2}
post : http://127.0.0.1:8080/api/Calculator.Add
body-raw : {Data={"N1":1,"N2":2}}

Offline

#12 2024-06-30 18:35:06

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

Read the mORMOt 1 documentation about SOA parameters.
https://synopse.info/files/html/Synopse … #TITLE_405

TL&WR: none/const = input; var = input and output; out = output

And you need to supply some real JSON: use Data: and not Data= for values.

Offline

#13 2024-07-01 13:08:27

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Thank you.  I fully understood how to use the interface without using orm.
I have a problem with the client. If I don't understand, I will ask.

Offline

#14 2024-07-03 07:20:38

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

I've looked through the v1 documentation as much as I can, but I'm still not sure how to connect to the TRestServerFullMemory server for communication on the client side when I'm not using a model and orm.
I used TRestHttpClient and set the model parameter to nil. But I get an accessviolation error in the ServiceDefine instruction.

Offline

#15 2024-07-03 07:28:08

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

You TRestServerFullMemory is for the server side. As its name states.

On client, use TRestHttpClientSocket and set a model with no TOrm class, but the same root value ('api').

Take a look at the mORMot 2 samples, you would find all that you need for this.

Offline

#16 2024-07-03 17:26:48

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

I reviewed the mormot2 examples. In the examples, everyone uses the model. sad

Offline

#17 2024-07-03 19:16:08

tbo
Member
Registered: 2015-04-20
Posts: 354

Re: Where do I start?

Kabiri wrote:

I reviewed the mormot2 examples. In the examples, everyone uses the model. sad

Why is this a problem?

With best regards
Thomas

Offline

#18 2024-07-03 21:45:46

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

tbo wrote:

Why is this a problem?

With best regards
Thomas

That's not the problem.The problem is how to do it.

APIs can generate different types of outputs.
For example:

  • A method that simply returns a number as the API version.

  • A simple method (like ping) that returns a simple value (for testing connectivity).

  • Up to complex methods that return a record or records from a database.

  • Or even files or streams.

Therefore, an API needs to be able to access all types of methods.

Last edited by Kabiri (2024-07-03 21:48:23)

Offline

#19 2024-07-04 01:00:44

lfyey121
Member
From: china
Registered: 2022-08-25
Posts: 66

Re: Where do I start?

Kabiri wrote:

I reviewed the mormot2 examples. In the examples, everyone uses the model. sad


Orm model can have no objects;

  TOrmModel.create([ ], arootName)

Offline

#20 2024-07-04 02:59:54

edwinsn
Member
Registered: 2010-07-02
Posts: 1,218

Re: Where do I start?

Don't be afraid my friend, Let me share with you my real life experience with mORMot 1 (even before Stephan Bester has written his excellent blog posts - not complete BTW, but it's still excellent), I have had success with mORMot 1 for several projects:

- I started with the examples.
- From time to time I encountered various questions/issues and all of them were addressed by one of the following:
  - Check the documentation - you don't have to go through it in one time because it's HUGE, just find the info you need.
  - Ask question here, ab the developer and other users were supper helpful and active.
  - Submit issue and ab usually solve the issue in less a day or several days depending on the severity.
  - And most of the time, check the source code and you'll get your answer.

One might have a steep learning curve with mORMot, and one might don't like the coding style wink, but it's DEFINITELY worth it because it's so feature-rich, stable, so fast and so fully-documented (the last point applies to v1 only, thus far, but I believe ab will fix it)! And the developer ab is so passionated and reliable, and the forum users are so active and helpful!

Last edited by edwinsn (2024-07-04 09:28:31)


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#21 2024-07-04 06:22:53

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

lfyey121 wrote:

Orm model can have no objects;

I understand. So in any case, the model must be created, but the model can be empty and not contain any objects.
Thanks

Offline

#22 2024-07-04 06:29:22

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Thanks @edwinsn smile
I am determined to learn mormot2. I can use it with the help of examples, but I wanted to understand how it works. I have a lot of questions on my mind and I hope to find the answers soon.

It would be great if this forum had a "thanks" button for posts.

Offline

#23 2024-07-04 09:46:30

edwinsn
Member
Registered: 2010-07-02
Posts: 1,218

Re: Where do I start?

Kabiri wrote:

Thanks @edwinsn smile
but I wanted to understand how it works.

There are different parts in the framework - ORM, web service and so on.
Take ORM for an example, if you know how published properties work in Delphi, how JSON works, know well enough about SQLite (including basic db concepts and virtual tables in SQLite), and so on, you can find out how it works.

Actually I know very little about the framework - there are a bunch of modules that I've not used yet. That being said, give the fact that the v2 version is lacking, I'd suggest you learn from v1, I believe everything is there for you to understand it - the full set of examples, the documentation and the source code.

I believe V2 is very similar to v1 in terms of the concepts and architecture, except that the code organization, the class names and some of the implementation have changed. Moreover, with a bunch of new features added - off the top of my head, I know there is a new quickjs-based engine, LDAP, X.509, OpenSSL 3.x, and so on - BTW, I think ab should include a "What's new in mORMot 2 section" in the github home page wink


Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.

Offline

#24 2024-07-04 11:08:24

rdevine
Member
Registered: 2014-02-20
Posts: 52

Re: Where do I start?

Kabiri wrote:

I am determined to learn mormot2

Definitely worth the effort - it's an excellent framework. I'd disagree with Edwin though - I'd concentrate on v2 and then back-reference to v1 when required. For v1 Stephan Bester's tutorials are very useful, as is https://tamingthemormot.wordpress.com/.

For more in-depth examples using v2 those by Thomas (tbo - mentioned above by flydev) are excellent.

Cheers, Bob

Offline

#25 2024-07-04 11:54:05

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Thanks @ab
Thanks @edwinsn
Thanks @rdevine

I think I'll be busy with this for a few days.
The question that's on my mind is whether it's possible to have multiple ORM models, multiple JSON outputs from the database, and non-model methods in a single API.

Offline

#26 2024-07-04 12:06:39

Márcio Baroni
Member
From: Brasil
Registered: 2015-10-07
Posts: 34

Re: Where do I start?

I've been using Mormot for a long time and it was really difficult at first.
If I can give one piece of advice, don't mix the ORM layer with the API layer.
Create ORM classes just to interact with the database.
Create another layer of classes (DTO) for your api or business rules...
With your DTO you can return whatever you want in your api without any relation to ORM, making it much cleaner.

Offline

#27 2024-07-04 12:07:35

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

Non-model methods in the API is indeed a clean way to go.
You can definitively do this. This is even the preferred way of using mORMot on production.

Use interface-based services, each implementing class instance with its own internal ORM model, i.e. its own TRestServerDB.
The idea is that if you use TRestServerDB locally on the server side, and don't publish it over HTTP, it won't be available but for the API itself.
So it is more a "TRestDB" than "TRestServerDB", to be precise.

Offline

#28 2024-07-05 20:43:52

mrbar2000
Member
From: Brazil
Registered: 2016-10-26
Posts: 93

Re: Where do I start?

When you told:

Create ORM classes just to interact with the database.
Create another layer of classes (DTO) for your api or business rules...

Means that i have to read the objects to TOrmObjects and manually transport the data to the DTO records?

sample:

In someplace of my apy i need get a baby then a call the repository. with the repository pattern I can isolate the orm of all my application (Clean Code)

procedure TBabyRepository.GetBaby(pID: Int64; var pDTOBaby: TDTOBaby);
var 
  Baby: TSQLBaby;   // store a record
begin
  Baby := TSQLBaby.Create;
  try
    TRestDB.Retrieve(pID, Baby);

    // transpose to DTO, TRestServerFullMemory can return to client
    pDTOBaby.ID := Baby.Id;
    pDTOBaby.Name := Baby.Name;
    pDTOBaby.Address := Baby.Address;
    pDTOBaby.BirthDate := Baby.BirthDate;
    pDTOBaby.Sex := Baby.Sex;    

  finally
    Baby.Free;
  end;
end;

this translate can be very slow approach depending!

I can do this of other way?

Last edited by mrbar2000 (2024-07-05 20:45:01)

Offline

#29 2024-07-05 20:48:32

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

If the field names do match, you can just fill the TBaby record from JSON, directly from the DB, with no transient TOrmBaby.

Offline

#30 2024-07-08 19:07:46

mrbar2000
Member
From: Brazil
Registered: 2016-10-26
Posts: 93

Re: Where do I start?

ab wrote:

If the field names do match, you can just fill the TBaby record from JSON, directly from the DB, with no transient TOrmBaby.

What Orm´s Method I can use for this?
My TDTOBaby is a packet record! I just see ORM.RetriveXXX(passing TORMClass)
Can you show a simple sample?

Offline

#31 2024-07-08 19:44:37

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

Search a little.
There are ORM methods returning JSON.
Then use this JSON to fill a TBaby record.

Offline

#32 2024-08-12 14:58:01

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Márcio Baroni wrote:

I've been using Mormot for a long time and it was really difficult at first.
If I can give one piece of advice, don't mix the ORM layer with the API layer.
Create ORM classes just to interact with the database.
Create another layer of classes (DTO) for your api or business rules...
With your DTO you can return whatever you want in your api without any relation to ORM, making it much cleaner.

Thank you for your explanation.
I generally prefer to keep the ORM and API layers separate. I'm not sure if this would cause a performance decrease.
I've been busy with other things for a while, but now I'm back to learning about Mormot. I want to create methods both with and without Models on a single server, and connect to it using a client.
I hope this isn't too difficult and I'm not bothering anyone.

Offline

#33 2024-08-12 15:35:37

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

I'm not sure I understand correctly.
Do you mean I should write an application server on a server and have an API connect to it as a client, retrieve database information, and then act as a server itself to send the data to the client (user side)?

Offline

#34 2024-08-12 16:16:49

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

No, all the logic on the server side.
But without publishing the database via ORM on the client side.
But publishing the data as high-level API methods, without any ORM, so without any TOrmModel - leaving [] for the tables list.

Offline

#35 2024-08-12 16:42:45

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Thank you. I will try it

Offline

#36 2024-08-13 13:51:34

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

@ab
I downloaded the new version of mormot2 yesterday.
In the mormot.core.base unit at line 36, the unit variants should be changed to system.variants.
Because it's giving a Circular unit reference to 'variants' error.
(Delphi 12.1)

Last edited by Kabiri (2024-08-13 13:52:22)

Offline

#37 2024-08-13 14:08:44

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

There is something wrong with your settings in the IDE, or of your project.
It seems to be a Delphi IDE bug, when importing the project.

See https://github.com/synopse/mORMot2/issues/240

Offline

#38 2024-08-13 17:01:37

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

In the unit 'mormot.core.variants', the unit 'mormot.core.base' is called,
which in turn calls 'variants'. However, the IDE mistakenly identifies it as 'mormot.core.variants'.
While this is indeed an IDE error (Or an unintentional setting in the IDE) , the easiest way to prevent this is to use 'system.variants' instead.

Last edited by Kabiri (2024-08-13 17:20:16)

Offline

#39 2024-08-13 17:26:15

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

If we change it, we would need to add $ifdef for FPC or older Delphi we still support, in all our units.

It was one goal of mORMot 2 to remove as many $ifdef as possible.
We won't start now.

Offline

#40 2024-08-13 17:40:27

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

Well, that's right. I hadn't thought about the FP.

Offline

#41 2024-08-13 18:58:35

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

I put a comment in the error place as reference.
https://github.com/synopse/mORMot2/commit/0998d945

Because this Delphi import "smart feature" is really confusing.
You are not the first to have been caught.
And won't be the last wink

Offline

#42 2024-08-14 08:57:59

anouri
Member
Registered: 2024-02-11
Posts: 49

Re: Where do I start?

This is a big challenge in the beginning. I had the same problem. First, I tried to work on the documentation with Json and how to work with it in mormot using docvariant and doclist. Then I went back to the examples and was able to modify it to create a very basic web service. Then I tried to understand the interface  base service and method base service . And finally I worked a little with swagger.
Considering that in my existing database, the primary keys are narural key and compiste. I can't use orm. Because in Orm there must be a primary key for each table. So, I leave this section aside and use the functions that take the model and store it in the database by SQL.
The next step is how to call and share the interface for the client program. The power of mormot shows itself here. And how beautifully this work is implemented.
I'm still at the beginning of the journey, but I learned a lot within a month and I try to learn more every day.
I agree that it is much more difficult to start working with mormot than other frameworks.

It is natural that piloting a plane is more difficult than driving a car. But there are many unique possibilities here. Thanks to AB

Last edited by anouri (2024-08-14 09:05:58)

Offline

#43 2024-08-14 11:50:10

Kabiri
Member
Registered: 2024-06-22
Posts: 38

Re: Where do I start?

In the examples, I only saw connections to SQLite. What should I do for MSSQLServer?
Which units should I add?
Previously, when accessing the database,
I created a connection and then closed it after retrieving the data. (In the events related to creating and destroying the class) And apparently here, when the server is running, the connection is created and remains open until the end of the server.

Offline

#44 2024-08-14 14:37:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

There is a connection pool, one connection per thread by default, which is maintain until the server is shut down.

Offline

#45 2024-08-14 15:12:52

anouri
Member
Registered: 2024-02-11
Posts: 49

Re: Where do I start?

this is my code to connect to mysql database. There are 2 service, invoice and inventory.

procedure TfrmMain.btnStartClick(Sender: TObject);
begin
  StartServer('zdbc:mysql://localhost:3306/mysqldb?username=user;password=mypassword');
end;

procedure TfrmMain.StartServer( aDbURI : RawUTF8 );
begin
  LogFamily := SQLite3Log.Family;
  LogFamily.Level := LOG_VERBOSE;
  LogFamily.PerThreadLog := ptIdentifiedInOnFile;

  MyModel := CreatePassakModel;

  aDbConnection := TSQLDBZEOSConnectionProperties.Create( aDbURI, '', '', '' );

  aPassakServer  := TRestServerFullMemory.Create(MyModel);
  InvoiceService := TInvoiceService.Create(aDbConnection);
  aPassakServer.ServiceRegister(InvoiceService, [TypeInfo(IInvoiceService)],'1');

  InventoryService := TInventoryService.Create(aDbConnection);
  aPassakServer.ServiceRegister(InventoryService, [TypeInfo(IInventoryService)],'2');

  aPassakServer.ServiceMethodRegister('reports', InvoiceService.testCallBack);

  AddToServerWrapperMethod(aPassakServer,['templates','templates']);

  aHTTPServer := TSQLHttpServer.Create( HttpPort, [aPassakServer], '+', HTTP_DEFAULT_MODE);

  aHttpServer.AccessControlAllowOrigin := '*'; // allow cross-site AJAX queries

  memLog.Lines.Add('Background server is running.'#10);
  memLog.Lines.Add('Cross-Platform wrappers are available at ' + HttpPort  + '/' +  HttpRoot );
end;

Offline

#46 2024-08-14 17:12:09

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,718
Website

Re: Where do I start?

Please don't put code directly in the forum threads, as stated by the forum rules.

How do you use the DB connection in TInvoiceService/TInventoryService methods?

Offline

#47 2024-08-15 08:02:47

anouri
Member
Registered: 2024-02-11
Posts: 49

Re: Where do I start?

ok
As you can see in the code above, I pass the dbconnection to the InvoiceService constructor. I inject connection by constructor to service, and I hold connection in fConnection defined inside service. I hope it is the right approach.
I am concerned about one thing. Is a connection shared between different threads created by mormot for other services or operations? Doesn't it cause a problem in Mormot being multi-thread?

Last edited by anouri (2024-08-15 08:23:48)

Offline

#48 2024-08-15 09:17:54

ttomas
Member
Registered: 2013-03-08
Posts: 135

Re: Where do I start?

Yes it is right approach. Just note, TSQL*ConnectionProperties is connection pool, not real db connection! Real db connection is TSQL*ConnectionProperties.ThreadSafeConnection and is created for your running thread. This connection is keep open and reuse for every call in same thread, because db connect is time expensive. I you really need to close thread connection you can call TSQL*ConnectionProperties.EndCurrentThread at the end of your interface/method.

Last edited by ttomas (2024-08-15 09:22:25)

Offline

#49 2024-08-15 14:50:12

anouri
Member
Registered: 2024-02-11
Posts: 49

Re: Where do I start?

thanks. but yo write "TSQL*ConnectionProperties is connection pool, not real db connection! Real db connection is TSQL*ConnectionProperties"
it is same!
TSQL*ConnectionProperties = TSQL*ConnectionProperties

Offline

#50 2024-08-15 19:37:37

tbo
Member
Registered: 2015-04-20
Posts: 354

Re: Where do I start?

anouri wrote:

As you can see in the code above, I pass the dbconnection to the InvoiceService constructor.

You must keep in mind that with the method you used to register the services, they are always sicShared. This is unimportant in a simple example, but you must take it into account for a server. But it is not necessary and with a little preparation you can implement it as shown in some examples.

Define your RestServer as follows:

type
  TMainRestServer = class(TRestServerFullMemory)
  strict private
    FConnectionPool: TSqlDBOdbcConnectionProperties;
  public
    property ConnectionPool: TSqlDBOdbcConnectionProperties
      read FConnectionPool;

CustomService as follows:

type
  ICustomService = interface(IInvokable)
    function GetConnection(out pmoConnection: TSqlDBConnection): Boolean;
  end;

type
  TCustomServiceObject = class(TInjectableObjectRest, ICustomService)
  protected
    function GetConnection(out pmoConnection: TSqlDBConnection): Boolean;

function TCustomServiceObject.GetConnection(out pmoConnection: TSqlDBConnection): Boolean;
begin
  Result := False;
  if TMainRestServer(Server).ConnectionPool <> Nil then
  begin
    pmoConnection := TMainRestServer(Server).ConnectionPool.ThreadSafeConnection;
    Result := (pmoConnection <> Nil);
  end;
end;

And use it in your services as follows:

var
  json: RawUtf8;
  dbConn: TSqlDBConnection;
  dbStmt: ISqlDBStatement;
begin
  if GetConnection(dbConn) then
  begin
    dbStmt := dbConn.NewStatementPrepared(...);
    dbStmt.ExecutePreparedAndFetchAllAsJson(False, json);

With best regards
Thomas

Offline

Board footer

Powered by FluxBB