The first step is to use Delphi XE new “DataSnap REST Application” wizard.
Select “File -> New -> Other” and from the “New Items” dialog double-click on the “DataSnap REST Application” icon in the “Delphi Projects -> DataSnap Server” category.

This wizard will create for us a complete system with a web application server and JavaScript client.
On the first screen of the wizard we can decide how our web application will be packaged. We have the option to create it as a DLL to be deployed into the IIS Web Server or as a standalone VCL application that will be both: a web server and a web application in one executable. This is new to Delphi XE and a very useful option for development, testing and deployment.

In the first screen of the wizard keep the default “WebBroker Project Type”, which is “Stand-alone VCL application”.

In the second screen of the wizard keep the default HTTP port 8080 and click on “Test Port” to see if it is available.

In the third screen of the wizard with “Server Features” keep the default selection.

Keep the default server methods ancestor class as well.

The last screen of the wizard is a little bit tricky. You have to select your project location. The last part of the path is also going to be our project name, so cannot contain spaces. It has to be a valid project name.

The wizard has generated for us lots of files in different subfolders. This a complete web application with cascading style sheets, images, JavaScript code, html templates and Delphi units with application logic.
Save All. Name the first unit “FormMainUnit” and the second unit “WebModuleMain”. The whole application will be called “DelphiLabsDataSnapRESTWebApp”.
Let’s have a little walk through different parts of our project.
Below is the main form of our application. This is also a kind of admin console for our web server. Buttons “Start” and “Stop” are respectively starting and stopping the web server. Pressing on “Open Browser” will launch a default web browser, which is going to host the actual client of our application: a web page with JavaScript code.

Below is the source code for the app main form generated by the wizard.
unit
FormMainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AppEvnts, StdCtrls, IdHTTPWebBrokerBridge, HTTPApp;
type
TFormMain = class
(TForm)
ButtonStart: TButton;
ButtonStop: TButton;
EditPort: TEdit;
Label1: TLabel;
ApplicationEvents1: TApplicationEvents;
ButtonOpenBrowser: TButton;
procedure
FormCreate(Sender: TObject);
procedure
ApplicationEvents1Idle(Sender: TObject; var
Done: Boolean);
procedure
ButtonStartClick(Sender: TObject);
procedure
ButtonStopClick(Sender: TObject);
procedure
ButtonOpenBrowserClick(Sender: TObject);
private
FServer: TIdHTTPWebBrokerBridge;
procedure
StartServer;
public
end
;
var
FormMain: TFormMain;
implementation
uses
ShellApi, DSService;
procedure
TFormMain.ApplicationEvents1Idle(Sender: TObject; var
Done: Boolean);
begin
ButtonStart.Enabled := not
FServer.Active;
ButtonStop.Enabled := FServer.Active;
EditPort.Enabled := not
FServer.Active;
end
;
procedure
TFormMain.ButtonOpenBrowserClick(Sender: TObject);
var
LURL: string
;
begin
StartServer;
LURL := Format('https://localhost:%s'
, [EditPort.Text]);
ShellExecute(0,
nil
,
PChar(LURL), nil
, nil
, SW_SHOWNOACTIVATE);
end
;
procedure
TFormMain.ButtonStartClick(Sender: TObject);
begin
StartServer;
end
;
procedure
TerminateThreads;
begin
if
TDSSessionManager.Instance <> nil
then
TDSSessionManager.Instance.TerminateAllSessions;
end
;
procedure
TFormMain.ButtonStopClick(Sender: TObject);
begin
TerminateThreads;
FServer.Active := False;
FServer.Bindings.Clear;
end
;
procedure
TFormMain.FormCreate(Sender: TObject);
begin
FServer := TIdHTTPWebBrokerBridge.Create(Self);
end
;
procedure
TFormMain.StartServer;
begin
if
not
FServer.Active then
begin
FServer.Bindings.Clear;
FServer.DefaultPort := StrToInt(EditPort.Text);
FServer.Active := True;
end
;
end
;
end
.
Check out the “FServer: TIdHTTPWebBrokerBridge” reference in the private section of the form class, which is instantiated inside the “FormCreate” event. This is this new Indy class that implements standalone web server functionality.
Now open the “WebModuleUnit”.

Every WebBroker web application has its own “web module”, which is the place where all HTTP requests arriving from clients are processed. A web module is a really just a specialized type of a data module.
If you click somewhere at the surface of this the web module, you should see its properties in the Object Inspector. Probably the most important property is “Actions”, which is a collection of actions that can be executed when an HTTP request arrives at the application.

Click on the ellipsis button next to “Actions” property to display actions collection editor.

Depending on the path info inside the HTTP request, a different action can be called to service a particular request and also specialized “producer” components can be used for this task.
Our web application contains two html templates (“ReverseString.html” and “ServerFunctionInvoker.html”), so there are also two “TPageProducer” components on the web module that are connected to individual actions.

Double-click on the “ReverseString.html” file in the Project Manager and you should see the Delphi HTML designer opening the “DataStap REST Project” page.

If you switch to the editor, you will find the following code generated by the wizard.
<!-- !DOCTYPE html PUBLIC
"-
OK. Let’s see how our Delphi XE DataSnap REST server behaves at runtime. Click on the green triangle icon in the IDE to run the project. It will display the main form of the application, which is in fact our web server console. Click on “Start” and “Open Browser”.
You should see something like this:

In my case this is a web page running in Chrome browser. If you click on the “ReverseString” button, you should see that the contents of the edit are reversed!
That’s a pure JavaScript client running in the browser that has no knowledge of Delphi!
Notice that clicking on the “ReverseString” button does not change the time when the page was initially loaded. This is great for the responsiveness of the web page and for the end user experience. The JavaScript files added by the wizard implements AJAX-style server method invocation, so we do not have to worry about it. That’s a very good thing!
Now click on the “Server Functions” link at the top of the page.
You should see the special “Server Function Invoker” test page, where you can call any of the available server methods.
Expand “TServerMethods1” class and its “ReverseString” method.
Enter a string in the “Value” field and click on the “EXECUTE” button. At the bottom of the screen you should see the JSON string with the original value and the result.

That’s cool! Now close the browser. Click “Stop” button on the server form and close the window.
Open server methods unit and remove test functions “EchoString” and “ReverseString”. Implement a different server method.
I have implemented a simple “Add” method that takes two doubles and returns a double.
unit
ServerMethodsUnit1;
interface
uses
SysUtils, Classes, DSServer;
type
TServerMethods1 = class
(TComponent)
private
public
function
Add(a, b: double): double;
end
;
implementation
function
TServerMethods1.Add(a, b: double): double;
begin
Result := a + b;
end
;
end
.
If you now rerun the application and open the “Server Function Invoker” you should see that the test page has been updated and now shows the “Add” method!

How this was possible? It looks a bit like magic.
The answer is in the “OnBeforeDispatch” event of the “WebFileDispatcher1” component in the web module:
procedure
TWebModuleMain.WebFileDispatcher1BeforeDispatch(Sender: TObject;
const
AFileName: string
; Request: TWebRequest; Response: TWebResponse;
var
Handled: Boolean);
var
D1, D2: TDateTime;
begin
Handled := False;
if
SameFileName(ExtractFileName(AFileName), 'serverfunctions.js'
) then
if
FileAge(AFileName, D1) and
FileAge(WebApplicationFileName, D2) and
(D1 < D2) then
begin
DSProxyGenerator1.TargetDirectory := ExtractFilePath(AFileName);
DSProxyGenerator1.TargetUnitName := ExtractFileName(AFileName);
DSProxyGenerator1.Write
;
end
;
end
;
The server methods proxy code is generated dynamically. If the “serverfunctions.js” file is out of date, then it is dynamically regenerated before the page is dispatched.
That is very useful and great for dynamic languages like JavaScript. You just do not need to worry. Your proxy code is always up-to-date.
Here we came to one of the strongest and most exciting new features in the DataSnap XE architecture: pluggable proxy generators!
If you select “DSProxyGenerator1” component on the form, and expand its “Writer” property you can see that generating proxy code for clients implemented in different programming languages is just a matter of selecting a different writer!

RAD Studio XE makes it possible to build DataSnap servers in Delphi and C++Builder, and clients in Delphi, C++, JavaScript, Delphi Prism and PHP.
That’s the Delphi multitier technology for the future!
Connect with Us