TMS XData Service Operations

Bookmarks: 

Friday, October 24, 2014

The latest TMS XData 1.1 version introduces a major feature: Service Operations. In addition to having your objects published as REST resources automatically, you can now add server-side logic in a very easy and straightforward way.

Service operations are defined as interfaces. Any interface can become a set of operations, all you need to do is add the [ServiceContract] attribute to the interface:
type
  [ServiceContract]
  IMyService = interface(IInvokable)
  ['{BAD477A2-86EC-45B9-A1B1-C896C58DD5E0}']
    function HelloWorld: string;
    function FindOverduePayments(CustomerId: integer): TList<TPayment>;
  end;
The nice thing is that in addition to sending and receiving values of scalar types, you can also send and receive Aurelius entities. You can also use TStream for low-level operations.

The next step is to write the server logic, which is done just by implementing the interface in some class, and adding the attribute [ServiceImplementation] to that class:
type
  [ServiceImplementation]
  TMyService = class(TInterfacedObject, IMyService)
  private
    function HelloWorld: string;
    function FindOverduePayments(CustomerId: integer): TList<TPayment>;
  end;
 
implementation
 
function TMyService.HelloWorld: string;
begin
  Result := 'Hello, World';
end;

function TMyService.FindOverduePayments(CustomerId: integer): TList<TPayment>;
begin
  Result := TXDataOperationContext.Current.GetManager.Find<TPayment>
    .CreateAlias('Customer', 'c')
    .Where(TLinq.Eq('c.Id', CustomerId) and TLinq.LowerThan('DueDate', Now))
    .List;
end;
And that's it. When you create the XData server module, it will find the interfaces and implementations automatically through the attributes, and will make the operations available through the server.

The FindOverduePayments method implementation illustrates how smooth is the integration with TMS Aurelius. The TXDataOperationContext class provides you with some useful properties to implement your server logic. The main property is GetManager, which provides you with an Aurelius TObjectManager.

All you have to do is use the manager to persist objects, or to query objects using the Aurelius full query API. When implementing the server logic, you don't have to deal with database connections (XData uses its connection pool), you don't need to instantiate the object manager, you don't need to deal with memory management and also with JSON serialization.

To invoke the service operation from any client using HTTP, you just POST to the operation address, passing the parameters in JSON format:
POST /tms/xdata/MyService/FindOverduePayments HTTP/1.1
 
{
  "CustomerId": 10
}
XData will parse the parameters, invoke your method, which in turn will use Aurelius to query the database, retrieve all TPayment objects that match the criteria, and return a plain JSON array with the payment objects in JSON format.

Another great thing is if your client is written in Dephi, you can use the TXDataClient class. You can then benefit from the interface you declared and use it at client side as well. Use the TXDataClient to retrieve the interface, and call the interface method. XData will do all the HTTP requesta and JSON conversion for you, and will give you the TPayment objects:
var
  Client: TXDataClient;
  MyService: IMyService;
  Payments: TList<TPayment>;
begin
  Client := TXDataClient.Create;
  Client.Uri := 'http://myserver/tms/xdata';
  MyService := Client.Service<IMyService>;
  Payments := MyService.FindOverduePayments(10);
  // add your logic that deals with TPayment objects
end;
You can even pass your Payments list to a TAureliusDataset to easily show them in a TDBGrid or any other control that is data aware or using Live Bindings.

You can learn more about XData using the official online documentation. Or you can refer directly to the Service Operations chapter.

Wagner R. Landgraf


Bookmarks: 

This blog post has received 6 comments.


1. Tuesday, October 28, 2014 at 12:04:17 PM

Hi,

Will this new feature be used in RemoreDB?

GHAZALI Abdesselam


2. Tuesday, October 28, 2014 at 12:25:32 PM

Hi, I don''t see how this feature could be used in RemoteDB, or the reason for it? RemoteDB is a way to directly access a remote database through http. Note that RemoteDB and XData are just Sparkle modules, you can have as many remotedb/xdata modules in an HTTP server as you want. Nothing prevents you from using RemoteDB for the direct database connection and have XData methods available.

Wagner Landgraf


3. Wednesday, October 29, 2014 at 7:45:49 AM

Thank you for the answer. I''m a little confused ... I''m looking for a way to convert mu current client-server application to n-tier, with smart queries to reduce bandwidth (because large databases).
I just bought Aurelius that helps me for the data CRUD part. I would like something like:
Client (Aurelius ORM) <-> Remote access (internet) <-> Server (Aurelius ORM) <-> Database (Firebird)
I have to focus on Sparke? XData? I am new to the product line, sorry.
Thank you in advance.


GHAZALI Abdesselam


4. Thursday, October 30, 2014 at 1:58:38 PM

In short RemoteDB allows TXDataset to send SQL statements via http to remote server, execute that SQL at server-side and returns dataset data in binary format. XData server in turn allows receiving http requests in JSON format, uses Aurelius on server side to access the database, and return back Aurelius objects in JSON format. If you want to have a more detailed technical discussion, I suggest using our support e-mail or support web forums.

Wagner Landgraf


5. Tuesday, October 18, 2016 at 3:03:06 PM

Hi.

How is none Aurelius attributed objects serilized? What''s the rules for such objects? I would emagine that everything that''s published is serilized, but what''s the other serilization rules?

/Brian

Brian Andersen


6. Tuesday, October 18, 2016 at 5:32:18 PM

When serializing Aurelius entities, only members (fields or properties) mapped are serialized (included in the JSON response). This allows to have complex classes with business logic (methods and mainly properties) that not necessarily should be persisted (thus serialized)

Wagner R. Landgraf




Add a new comment:
Author:
Email:
  You will receive a confirmation mail with a link to validate your comment, so please use a valid email address.
Comment:
 
Change Image
Fill in the characters from the image above:
 

All fields are required.
 




Previous  |  Next  |  Index