#1 2013-01-04 12:42:34

LoPiTaL
Member
Registered: 2013-01-04
Posts: 30

Interfaced based services or direct access to database?

Hi everyone!
I am a bit new to this framework and to the technologies related, so maybe my question is a bit stupid, but I couldn't find any suitable answer anywhere.

I have wroten a test server (using TSQLRestServerDB), which has a service that provides basic access to the database as follows:

  TDatabaseRecord=record
    Name: string;
    Age: integer;
  end;
  TDatabaseRecordArray=array of TDatabaseRecord;

  IDatabaseService=interface(IInvokable)
    ['{9ABC8235-5102-4C02-8469-0BCA606C1CF0}']
    function Add(const ARecord: TDatabaseRecord): integer;
    procedure Delete(AIndex: integer);
    procedure List(var ARecords: TDatabaseRecordArray);
  end;

The class implementing this service uses a class inherited from TSQLRecord to access the database. This class has similar parameters to the record TDatabaseRecord.

TSQLPerson = class(TSQLRecord)
  private
    FName: RawUTF8;
    FAge: integer;
  published
    property Age: integer read FAge write FAge;
    property Name: RawUTF8 read fName write fName;
  end;

The client uses the interface to connect to the server and everything works OK.

But then I thought, why don't use the TSQLPerson class directly in the client, so it can access directly to the database bypassing all the process the service has to do?

It worked also, of course.

So my question is: which way is better? Are the services meant to be used like this? Is it safer to access directly to the database from clients? I started with the services way thinking that may be more secure the usage of services instead of direct accessing. But since the framework already has a lot of security functionalities maybe I am overloading the server without achieving anything...

Note that my clients will be AJAX basically, not Delphi clients (don't know if it is relevant).

Best regards,
LoPiTaL

Offline

#2 2013-01-04 13:03:21

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

Re: Interfaced based services or direct access to database?

Your question is interesting.

In fact, for TSQLRecord / ORM remote access, you have already all Client-Server CRUD operations available.
It has been optimized a lot (e.g. with a cache and other nice features), so I do not think reinventing a CRUD / database service is worth the prize.
You have secure access to the ORM classes, with user/group attributes.

In fact, architecturally speaking, your question faces another point: the layer separation.
In a Domain-Driven-Design project, for instance, you may make a difference between persistence objects aka entitities (i.e. TSQLRecord) and value objects (e.g. records).
So your exposed service at application may not know anything about the ORM / DB definitions of the Domain layer.
In DDD, you develop your application layer services directly from the needs of your client applications, using the Domain layer to focus on the business logic and persistence.

If you use AJAX clients, high-level only services, with records (which will be mapped as JavaScript objects) does make sense.
Our ORM / TSQLRecord classes does amazing work in the world of Delphi classes (including filtering or validation, strong typing, and abstract TSQLRest CRUD methods), but for AJAX clients, the benefit is less obvious.
So AJAX does make a difference here.

That's why, for your case with AJAX clients, I would tend to make services with small records dedicated to your client applications, or even TSQLRecord (which will be published as JavaScript objects) in some cases.
It will depend on the nature of your business logic.
Don't be afraid of writing some translation layers between TSQLRecord and records (i.e. entities and value objects). It will be very fast, on the server side.  If your service interfaces are cleaner, don't hesitate. But if it tends to enforce you writing a lot of wrapping code, forget about it.
You have to weight the PROs and the CONs, like always...

Offline

#3 2013-01-04 13:36:48

LoPiTaL
Member
Registered: 2013-01-04
Posts: 30

Re: Interfaced based services or direct access to database?

Hi ab, thank you for your quick and detailed answer.

ab wrote:

It has been optimized a lot (e.g. with a cache and other nice features), so I do not think reinventing a CRUD / database service is worth the prize. You have secure access to the ORM classes, with user/group attributes.

Yes, this is what I thought and what made me doubt.

ab wrote:

In fact, architecturally speaking, your question faces another point: the layer separation.

I didn't thought about it, but it is interesting. I will have this into account in the future

ab wrote:

Don't be afraid of writing some translation layers between TSQLRecord and records (i.e. entities and value objects). It will be very fast, on the server side.  If your service interfaces are cleaner, don't hesitate. But if it tends to enforce you writing a lot of wrapping code, forget about it.

Ok. I get the point.

Thank you very much for the answer! It has been very explanatory.

Best regards,
LoPiTaL

Offline

#4 2013-01-04 14:24:54

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

Re: Interfaced based services or direct access to database?

As extracted from the SAD document:

From the Domain-Driven / SOA point of view, it is now an established rule to make a distinction between DTO (Data Transfer Objects) and Domain Values (Entity objects or Aggregates). In most implementations, persistence objects (aka ORM objects) should be either the aggregate roots themselves (you do not store Entity objects and even worse DTOs), either dedicated classes. Do not mix layers, unless you like your software to be a maintenance nightmare!

Happy it helped.

Note that in order to serialize the TDatabaseRecord records as pure JSON, you would need to code the writer and reader rountines by hand, whereas it is already included with TSQLPerson.
See http://blog.synopse.info/post/2012/05/0 … of-records

Offline

#5 2013-01-05 19:24:24

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

Re: Interfaced based services or direct access to database?

I've written some new blog article, which may help you, from the architectural point of view.
See http://blog.synopse.info/post/2013/01/0 … and-mORMot

Starting point of it was your question here.
Thanks!

Offline

#6 2013-01-06 20:17:34

LoPiTaL
Member
Registered: 2013-01-04
Posts: 30

Re: Interfaced based services or direct access to database?

ab wrote:

I've written some new blog article, which may help you, from the architectural point of view.
See http://blog.synopse.info/post/2013/01/0 … and-mORMot

Starting point of it was your question here.
Thanks!

I have never thought that my question was so deep big_smile I am going to read your article right now!

ab wrote:

Note that in order to serialize the TDatabaseRecord records as pure JSON, you would need to code the writer and reader rountines by hand, whereas it is already included with TSQLPerson.

So this is really important if I am using an AJAX client, and didn't want to write too much code... I have read the SAD document before starting (quite strange in me big_smile), but when I began to write the code I forget about this detail (is really extense the SAD document....). So, I think that the best way to go is using directly the access to the database where the coding to standard JSON is already implemented and I have only to code the AJAX part.

Best regards,
LoPiTaL

Offline

#7 2013-01-06 20:28:15

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

Re: Interfaced based services or direct access to database?

This blog article is part of the update documentation.

About the documentation, ensure you read the latest "unstable" version, i.e. 1.18.
See http://synopse.info/files/pdf/Synopse%2 … 201.18.pdf

It is modified very often, and the 1.18 revision should be easier to follow than 1.17, due to a deep refactoring into smaller chapters, and a lot of enhancements / modifications.

Thanks for the feedback!

Offline

Board footer

Powered by FluxBB