Show / Hide Table of Contents

    Getting Started

    It's very easy to get your first XData server and client applications running:

    1. Create and run an "empty" server

    2. Add your server-side logic using service operations

    3. Send requests to the server from clients

    4. (Optional) Automatically publish your existing Aurelius entities

    1. Create and run an "empty" server

    a. From Delphi IDE, choose File > New > Other;

    b. From the dialog that appears, navigate to Delphi Projects > TMS XData;

    c. Double click "TMS XData VCL Server" to create the server.

    Done: a new project will be created, run it, and your server will be running at the address "http://localhost:2001/tms".

    You have several different options for this step:

    • Creating the Server Using the XData Server Wizards

    • Creating the Server Using Design-Time Components

    • Creating the Server Manually

    Using the "XData Server Wizards" is just the more straightforward way to create a new server.

    If you don't like wizards, you can simply create a new blank application and drop a couple of design-time components to create your server.

    If you don't like design-time components and you want to do it 100% from code, just create the server manually.

    2. Add your server-side logic using service operations

    a. From Delphi IDE, choose File > New > Other;

    b. From the dialog that appears, navigate to Delphi Projects > TMS XData;

    c. Double click "TMS XData Service" to create a new service. Use the default settings for now.

    Done: Two new units will be created, including two server-side sample methods: Sum and EchoString. Your server is doing something!

    Using "XData Service Wizard" is just the more straightforward way to add server-side logic.

    If you don't like wizards, you can simply create your service operations manually from code, creating a ServiceContract interface and ServiceImplementation class.

    Your server is ready! Let's connect to it now!

    3. Send requests to the server from clients

    Connecting from Delphi client applications

    If you are connecting to server from a Delphi application, accessing your server could not be easier. All you need is to use the TXDataClient object:

    uses {...},  MyService, XData.Client;
    
    var
      Client: TXDataClient;
      MyService: IMyService;
      SumResult: Double;
    begin
      Client := TXDataClient.Create;
      Client.Uri := 'http://localhost:2001/tms/xdata';
      SumResult := Client.Service<IMyService>.Sum(10, 5);
      Client.Free;
    end;
    

    And that's it! You invoke XData methods as if they were regular procedures in your client application. The MyInterface unit and IMyService interface were created in the previous step above. You just reuse the same code so that in client you don't have to do anything else but call the interface method.

    Of course, there are much more advanced features you can use, so you can learn more about TXDataClient.

    Connecting from non-Delphi client applications

    To invoke the same Sum operation above without TXDataClient, just perform an HTTP request:

    GET /tms/xdata/myservice/sum?a=10&b=5 HTTP/1.1
    Host: localhost:2001
    

    And you will get your response in JSON format:

    {
      "value": 15
    }
    

    Of course you can simply go to your web browser and navigate to address "http://localhost:2001/tms/xdata/myservice/sum?a=10&b=5" to test it.

    XData server is a standard REST/JSON server. Meaning you can access it from any client application that can simply handle JSON and perform HTTP applications. That means virtually all kinds of applications: desktop, web, mobile, IoT, etc., regardless if those applications were built in C# .NET, Java, PHP, JavaScript, TypeScript, C/C++, Swift, etc.

    4. (Optional) Automatically publish your existing Aurelius entities

    If you use TMS Aurelius, then TMS XData can automatically create CRUD endpoints for some or all of your Aurelius entities. It's a nice feature that saves you time. Note that this is optional, TMS XData doesn't require you to use TMS Aurelius at all.

    How to continue from this

    Now you can implement your real server. Of course XData allows you to create complex service operations, not just simple ones like the Sum above.

    You can receive and return parameters of many different types: primitive types like integers, doubles, strings, guids, dates; complex types like object and arrays; and several specific supported types like strings, streams, etc..

    When using non-Delphi clients, it's interesting to learn how routing and parameter binding works, so you know exactly how to invoke a service operation from a non-Delphi application. It's also important to understand how JSON serialization works (how each Delphi type is represented as JSON) to know how to build the JSON to be sent, and how to interpret the received JSON.

    Note

    Any XData HTTP server is based on the TMS Sparkle framework. According to the Sparkle documentation, to use the Windows (http.sys) based server, you must first reserve the URL your service will process its requests from. If you have installed TMS Sparkle on your computer, the URL "http://+:2001/tms" is already reserved, so you can create your XData server under that address (all examples in this documentation use the base address "http://server:2001/tms/xdata". If you change your base URL to a different port, or to a URL that doesn't start with "tms", you must reserve that URL otherwise your server might fail to start.

    Creating the Server Using the XData Server Wizards

    The easiest and more straightforward way to get started with XData is using the wizards.

    1. Choose File > New > Other and then look for the TMS XData category under "Delphi Projects".

    2. There you find several wizards to create a new XData Server Application:

      • TMS XData VCL Server: Creates a VCL application that runs an XData server using http.sys
    3. Choose the wizard you want, double-click and the application will be created.

    As soon as you execute your application, the server is run. The application generated uses the design-time components. Simply learn about the components to configure them. For example, you can drop a TFDConnection component and set it to the TAureliusConnection.AdaptedConnection property to associate a database connection with the XData server.

    You can also create the server manually. The wizard is not mandatory and it is one way to get started quickly.

    Creating the Server Using Design-Time Components

    If you don't want to use the XData Server Wizard, another way to create a XData Server is by manually dropping the design-time components. If you want the RAD, component dropping approach, this is the way to go.

    1. Drop a dispatcher component on the form/data module (for example, TSparkeHttpSysDispatcher).

    2. Drop a TXDataDBServer component on the form/data module.

    3. Associate the TXDataDBServer component with the dispatcher through the Dispatcher property.

    4. Specify the BaseUrl property of the server (for example, http://+:2001/tms/xdata).

    5. Set the Active property of the dispatcher component to true.

    That's all you need. If you want to have a ready-to-use database connection pool, you can use the following extra steps:

    6. Drop a TAureliusConnection component on the form/data module and configure it so that it connects to your database (you will need to drop additional database-access components, e.g. TFDConnection if you want to use FireDac, and then associate it to the TAureliusConnection.AdaptedConnection).

    7. Drop a TXDataConnectionPool component on the form/data module and associate it to the TAureliusConnection component through the Connection property.

    8. Associate the TXDataServer component to the TXDataConnectionPool component through the Pool property.

    Creating the Server Manually

    Here we describe the steps to create the XData server manually, from code, without using XData Server Wizard or the design-time components:

    1. Create an IDBConnectionFactory interface

    2. Create an IDBConnectionPool interface

    3. Create a TXDataServerModule object

    4. Create a THttpSysServer, add the module to it and start the server

    1. Create an IDBConnectionFactory interface

    The IDBConnectionFactory interface is used to create TMS Aurelius IDBConnection interfaces which will be used by the server to connect to the desired database (in that database Aurelius objects will be persisted). You can read more details on the specific topic here: IDBConnectionFactory interface.

    Below we provide a code example that creates an IDBConnectionFactory interface which produces IDBConnection interfaces that connect to an MS SQL Server database, based on an existing TSQLConnection component named SQLConnection1 in a data module TMyConnectionDataModule.

    uses 
      {...}, Aurelius.Drivers.Interfaces, Aurelius.Drivers.Base,
      Aurelius.Drivers.dbExpress;
    
    var
      ConnectionFactory: IDBConnectionFactory;
    begin
      ConnectionFactory := TDBConnectionFactory.Create(
        function: IDBConnection
        var
          MyDataModule: TMyConnectionDataModule;
        begin
          MyDataModule := TMyConnectionDataModule.Create(nil);
          Result := TDBExpressConnectionAdapter.Create(MyDataModule.SQLConnection1, MyDataModule);
        end
      ));
    
      // Use the ConnectionFactory interface to create an IDBConnectionPool interface
    end;
    

    2. Create an IDBConnectionPool interface

    The IDBConnectionPool interface is used by the server to retrieve an IDBConnection interface when it is needed. It holds a list of such interfaces, and if there is none available, it uses the IDBConnectionFactory interface to create a new one. Example:

    uses 
      {...}, Aurelius.Drivers.Interfaces, XData.Aurelius.ConnectionPool;
    
    var
      ConnectionPool: IDBConnectionPool;
      ConnectionFactory: IDBConnectionFactory;
    begin
      {...}
      ConnectionPool := TDBConnectionPool.Create(
        50, // maximum of 50 connections available in the pool
            // Define a number that best fits your needs
        ConnectionFactory
      );
    
      // Use the IDBConnectionPool interface to create the XData server module
    end;
    

    3. Create a TXDataServerModule object

    The TXDataServerModule is the main class of the XData server. It is a Sparkle server module that is added to the Sparkle server for a specific address. Example:

    uses
      {...}, XData.Server.Module;
    var
      XDataModule: TXDataServerModule;
      ConnectionPool: IDBConnectionPool;
    begin
      {...}
      XDataModule := TXDataServerModule.Create('http://+:2001/tms/xdata', ConnectionPool);
    

    4. Create a THttpSysServer, add the module to it and start the server

    Finally, create a TMS Sparkle THttpSysServer object, add the XData module to it, and start the server. Example:

    uses
      {...}, Sparkle.HttpSys.Server, XData.Server.Module;
    var
      XDataModule: TXDataServerModule;
      Server: THttpSysServer;
    begin
      Server := THttpSysServer.Create;
      Server.AddModule(XDataModule);
      Server.Start;
    end;
    

    Later on, do not forget to destroy the Server object instance when the application finishes.

    Example 1: In-memory SQLite for testing/development

    The following example is a minimum console application that illustrates how to start an XData server at address "http://localhost:2001/tms/music" using an in-memory SQLite database. It uses an unit named AureliusEntities which is not shown here for simplification. Such a unit should just contain the Aurelius mapped classes that will be exposed by the server.

    An extra note about this example: Since it is an in-memory database, the database will be empty every time the server starts. Thus, before the server starts, the method "UpdateDatabase(Connection)", which is declared in unit DatabaseUtils (also not listed here), will be called to create the required tables and data. Such a thing is a regular TMS Aurelius procedure and is out of the scope of this example as well. The purpose of this example is to show how to start an XData server.

    program SQLiteConsoleServer;
    
    {$APPTYPE CONSOLE}
    
    uses
      System.SysUtils,
      Aurelius.Drivers.Interfaces,
      Aurelius.Drivers.SQLite,
      Aurelius.Sql.SQLite,
      Aurelius.Schema.SQLite,
      Sparkle.HttpSys.Server,
      XData.Aurelius.ConnectionPool,
      XData.Server.Module,
      AureliusEntities,
      DatabaseUtils;
    
    procedure StartServer;
    var
      Server: THttpSysServer;
      Connection: IDBConnection;
    begin
      Server := THttpSysServer.Create;
      try
        Connection := TSQLiteNativeConnectionAdapter.Create(':memory:');
        UpdateDatabase(Connection);
        Server.AddModule(TXDataServerModule.Create('http://localhost:2001/tms/music',
          TDBConnectionPool.Create(1,
            function: IDBConnection
            begin
              Result := Connection;
            end)));
        Server.Start;
        WriteLn('Server started. Press ENTER to stop.');
        ReadLn;
      finally
        Server.Free;
      end;
    end;
    
    begin
      StartServer;
    end.
    

    Example 2: MySQL Server with dbExpress (from Delphi code)

    The following example is a minimum console application that illustrates how to start an XData server at address "http://localhost:2001/tms/music" using dbExpress to connect to a MySQL database. It is configured in code. It uses an unit named AureliusEntities which is not shown here for simplification. Such a unit should just contain the Aurelius mapped classes that will be exposed by the server.

    The connection pool is configured to hold up to 25 connections to the database.

    program DBExpressConsoleServer;
    
    {$APPTYPE CONSOLE}
    
    uses
      System.SysUtils, SqlExpr, DBXMySQL,
      Aurelius.Drivers.Base,
      Aurelius.Drivers.Interfaces,
      Aurelius.Drivers.dbExpress,
      Aurelius.Sql.MySQL,
      Aurelius.Schema.MySQL,
      Sparkle.HttpSys.Server,
      XData.Aurelius.ConnectionPool,
      XData.Server.Module,
      AureliusEntities in '..\common\AureliusEntities.pas';
    
    procedure StartServer;
    var
      Server: THttpSysServer;
      ConnFactory: IDBConnectionFactory;
    begin
      Server := THttpSysServer.Create;
      try
        // Example using dbExpress. Create a connection factory to use later
        ConnFactory := TDBConnectionFactory.Create(
          function: IDBConnection
          var
            SqlConn: TSQLConnection;
          begin
            SqlConn := TSQLConnection.Create(nil);
            SqlConn.DriverName := 'MySQL';
            SqlConn.GetDriverFunc := 'getSQLDriverMySQL';
            SqlConn.VendorLib := 'libmysql.dll';
            SqlConn.LibraryName := 'dbxmys.dll';
            SqlConn.Params.Values['HostName'] := 'dbserver';
            SqlConn.Params.Values['Database'] := 'xdata';
            SqlConn.Params.Values['User_Name'] := 'user';
            SqlConn.Params.Values['Password'] := 'mysql';
            SqlConn.LoginPrompt := false;
            Result := TDBExpressConnectionAdapter.Create(SqlConn, true);
          end
        );
        Server.AddModule(TXDataServerModule.Create(
          'http://localhost:2001/tms/music',
          TDBConnectionPool.Create(25, ConnFactory)
        ));
        Server.Start;
        WriteLn('Server started. Press ENTER to stop.');
        ReadLn;
      finally
        Server.Free;
      end;
    end;
    
    begin
      StartServer;
    end.
    

    Example 3: MS SQL Server with FireDAC (using TDataModule)

    The following example illustrates how to start an XData server at address "http://localhost:2001/tms/music" using FireDac to connect to any database (in the example, a MS SQL Server database). Compared to Example 2, this example uses a TFDConnection dropped onto a TDataModule to configure the database connection at design-time. It uses an unit named AureliusEntities which is not shown here for simplification. Such a unit should just contain the Aurelius mapped classes that will be exposed by the server. The connection pool is configured to hold up to 15 connections to the database.

    Thus, consider you have a data module with an existing configured database connection using FireDac:

    example datamodule fdconnection

    You can use such a configuration and create one instance of that data module when required by the server. You can use the TFDConnection component from it.

    program FireDacConsoleServer;
    
    {$APPTYPE CONSOLE}
    
    uses
      System.SysUtils,
      Aurelius.Drivers.Base,
      Aurelius.Drivers.Interfaces,
      Aurelius.Drivers.FireDac,
      Aurelius.Sql.MSSQL,
      Aurelius.Schema.MSSQL,
      Sparkle.HttpSys.Server,
      XData.Aurelius.ConnectionPool,
      XData.Server.Module,
      AureliusEntities in '..\common\AureliusEntities.pas',
      DBDataModuleUnit in 'DBDataModuleUnit.pas' {DBDataModule: TDataModule};
    
    procedure StartServer;
    var
      Server: THttpSysServer;
    begin
      Server := THttpSysServer.Create;
      try
        Server.AddModule(TXDataServerModule.Create('http://localhost:2001/tms/music',
          TDBConnectionPool.Create(15, TDBConnectionFactory.Create(
            function: IDBConnection
            var
              DBDataModule: TDBDataModule;
            begin
              // Example using FireDac and Data Module
              DBDataModule := TDBDataModule.Create(nil);
              Result := TFireDacConnectionAdapter.Create(DBDataModule.FDConnection1, DBDataModule);
            end
        ))));
        Server.Start;
        WriteLn('Server started. Press ENTER to stop.');
        ReadLn;
      finally
        Server.Free;
      end;
    end;
    
    begin
      StartServer;
    end.
    
    Back to top TMS XData v4.17
    © 2002 - 2021 tmssoftware.com