How to create an API(WebServer) in Delphi

Soon Sam Santos
5 min readJul 11, 2019
Photo by William Hook on Unsplash

An API is a very powerful feature when you want your app working on a Tablet, Smartphone, Desktop or a Website. You can integrate all your platforms and have your app working on multiple platforms calling the same database.

When it comes to web server, Delphi is a superpower. I built an API with over 10 endpoints for my mobile app in only two full days of work. It is concise, easy and very fast.

I will be using Delphi 10.2 throughout this article.

Let’s start

Step 1. Create your project

File-> New -> Other

It will open a window, in the left select Delphi Projects->DataSnap Server

In the right, Select and Create: DataSnap WebBroker Application

Keep pressing Next until the end. You can select all the defaults by now.

Step 2. Check your files

You should have the following Files tree

Project
- FormUnit1.pas
- ServerMethodsUnit1.pas
- WebModuleUnit1.pas

FormUnit1.pas

It is your form, this is where you will start/stop the service and select the port.

ServerMethodsUnit1.pas

We are not going to use this one. This will be used when working with DataSnap. Today it is not the case!

WebModuleUnit1.pas

This is where the magic will happen, here we will create the endpoints and write our code.

Step 3. First Test!

  • Go to WebModuleUnit1.pas ;
  • Select design to go to your form;
  • In Structure Panel in the left do a right click in Actions and click in Add Item .
  • A new item will be added in the tree. Click in the Item and go to your Object Inspector to change the properties.
A picture in case you didn’t understand.

Put the following properties:

MethodType = mtGet
Name = actClients
PathInfo = /clients

MethodType

Here it is where you say if you are going to get, delete, put or post data. In our case we are going to get a list of clients.

Name

This property is only the name. It matters you follow a pattern so your peers will understand your code.

PathInfo

This is your endpoint, people will call your BaseUrl followed by the endpoint.

For example in GitHub API when you call the following URL.

https://api.github.com/users

/users is the endpoint!! :)

Step 4. Configure your response

In the Object Inspector change from properties to Events and double click in OnAction to generate the action procedure.

This will generate a procedure for the action we are working on. This is where we are going to write our code that will be the response for the client.

procedure TWebModule1.WebModule1actClientsAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
// TODO Write login and send the response
end;

Now, we are going just to write a dumb code to test our server.

procedure TWebModule1.WebModule1actClientsAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.Content := '{It worked}';
end;

At last, run and start your server. Call from any browser the following url.

http://localhost:8080/clients

And you should the our dumb code on the screen.

Step 5. Calling MySQL

Now you can work whatever code you want in this action and return any response you want to the user. (This will be probably a JSON response, more tips in next step).

I will not work on connection to MySQL on this article, however I did two articles about that you can check it before keep reading.

Connect MySQL localhost to Delphi using FireDac

Connecting Interbase database sample to Delphi App — FireDac

You can connect a MySQL server, either local, remote or Interbase samples and call a table (in our case it would be a table of clients). After all you would add all the columns you got in a JsonObject and send as the response.

Step 6. Example and more about JSON

Here you will check an example and you will learn how to create and the response in JSON . Of course, this connection won’t work for you because I am calling my localhost.

procedure TWM.WMactLoteamentosAction(Sender: TObject; Request: TWebRequest;
Response: TWebResponse; var Handled: Boolean);
var
qryClients: TFDQuery;
JsonArray: TJSONArray;
JsonObject: TJSONObject;
begin
// Configure response
Response.ContentType := 'application/json; charset=utf-8';
// Search for my clients table
qryClients:= TFDQuery.Create(nil);
with qryClients do
begin
Connection := FDConnection;
Active := False;
SQL.Clear;
Open('SELECT * FROM clients'); if qryLoteamentos.RecordCount > 0 then // If there are items
begin
JsonArray := TJSONArray.Create;
try
First;
while not Eof do // Iterate all items in the FDQuery
begin
JsonObject := TJSONObject.Create;
AddFieldsToJSON(JsonObject, qryLoteamentos);
JsonArray.AddElement(JsonObject);
Next;
end;
finally
Response.Content := JsonArray.ToString;
JsonArray.DisposeOf;
end;
end;
end;
end;
procedure AddFieldsToJSON(AJsonObject: TJSONObject;
AQuery: TFDQuery);
begin
with AQuery do
begin
AJsonObject.AddPair('id', TJSONNumber.Create(FieldByName('id').AsInteger));
AJsonObject.AddPair('name', FieldByName('name').AsString);
AJsonObject.AddPair('country', FieldByName('country').AsString);
end;
end;

This would get a response like that:

[
{
"id": 1,
"name": "Maria Eduarda",
"country": "Brazil"
},
{
"id": 2,
"name": "Maria Clara",
"country": "Brazil"
},
{
"id": 3,
"name": "Maria Vitória",
"country": "Brazil"
}
]

To understand the structure, the [] indicates a JSONArray and the {} indicates a JSONObject .

Black is the array and Blue are the JSONObjects.

Additional

In case you are thinking about how to send parameters to your server. I will teach you right now.

Query Parameters

For searching query parameters you just need to call Request.QueryFields .

Let’s take the following url: http://localhost:8080/clients?id_client=1

if Request.QueryFields.Count > 0 then
ClientID := Request.QueryFields.Values['id_client'];

Body Parameters

If you want to send parameters in the body you can send it as a Json. For example if you send the following body.

{
"name": "Maria Eduarda",
"country": "Brazil"
}

You could get the fields with the following code.

var
RequestObject: TJSONObject;
Name, Country: string;
begin
RequestObject := TJSONObject.ParseJSONValue(Request.Content) as TJSONObject;
Name := RequestObject.GetValue('name').Value;
Country := RequestObject.GetValue('country').Value;
end;

Happy coding!

--

--

Soon Sam Santos

Flutter and Delphi Developer at Green. Teacher at SoonClass