RAD Server: Mapping Web Properties to Folders

by Mar 14, 2020

In my Embarcadero Academy RAD Server courses, “Using Delphi and RAD Server to Rapidly Design, Build, Debug, and Deploy Services-Based Solutions” and “Using C++Builder and RAD Server to Rapidly Design, Build, Debug, and Deploy Services-Based Solutions“, i show Delphi and C++Builder developers how to integrate code with JavaScript, HTML, images, CSS, and other web asset files in an application’s resource endpoints.

The RAD Server configuration file (emsserver.ini) section labeled [Server.PublicPaths] contains information and examples for setting up public paths of web content. Server Public Paths entries have a unique arbitrary name that precedes the equal sign. The JSON based entries map a computer directory to the types of web information that a RAD Server application can use. Each entry contains a “path”: “value”, directory where files are found, optional default file to dispatch upon browsing, optional array of MIME file type masks, optional array of file extensions, and optional character set encoding for the files in the directory.

For an example, with the following path entries to the RAD Server configuration file in the [Server.PublicPaths] section:

Path1={“path”: “images”, “directory”: “C:\\WebAssets\\images\\”, “default”: “index.html”, “mimes”: [“image/*”]}
Path2={“path”: “content”, “directory”: “C:\\WebAssets\\content\\”, “default”: “index.html”, “extensions”: [“js”, “html”, “css”]}

Create the C:\WebAssets\Content and C:\WebAssets\Images directories. Create an index.html file in the C:\WebAssets\Content directory containing the following HTML:

<!DOCTYPE html>
<html>
<head>
<script src=”https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js”>
</script>
<script>
$(document).ready(function(){
$(“button”).click(function(){
$.ajax({url: “/WebProperties”, success: function(result){
$(“#div1″).html(result);
}});
});
</script>
</head>
<body>
<h2>RAD Server JS + Service</h2>
<button>Get RAD Server Content</button>
<P></p>
<div id=”div1”>RAD Server GET method result will appear here</div>
</body>
</html>

Add the following code for the implementation of the Get and GetItem endpoints.

Delphi:

unit ResourceUnit;

// EMS Resource Module

interface

uses
  System.SysUtils, System.Classes, System.JSON,
  EMS.Services, EMS.ResourceAPI, EMS.ResourceTypes;

type
  [ResourceName('WebProperties')]
  TWebPropertiesResource1 = class(TDataModule)
  published
    procedure Get(const AContext: TendpointContext;
	const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
    [ResourceSuffix('{item}')]
    procedure GetItem(const AContext: TendpointContext;
	const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
  end;

implementation

{%CLASSGROUP 'System.Classes.TPersistent'}

{$R *.dfm}

procedure TWebPropertiesResource1.Get(const AContext: TendpointContext;
	const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
begin
  Aresponse.Body.SetValue(TJSONString.Create(
    'WebProperties get method called at ' + TimeToStr(Now)), True)
end;

procedure TWebPropertiesResource1.GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);
var
  LItem: string;
begin
  LItem := ARequest.Params.Values['item'];
  AResponse.Body.SetValue(TJSONString.Create('WebProperties ' + LItem), True)
end;

procedure Register;
begin
  RegisterResource(TypeInfo(TWebPropertiesResource1));
end;

initialization
  Register;
end.

C++:

//---------------------------------------------------------------------------
#pragma hdrstop

#include "ResourceUnit.h"
#include <memory>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma classgroup "System.Classes.TPersistent"
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
__fastcall TWebPropertiesResource1::TWebPropertiesResource1(TComponent* Owner)
	: TDataModule(Owner)
{
}

void TWebPropertiesResource1::Get(TEndpointContext* Acontext,
	TEndpointRequest* ARequest, TEndpointResponse* AResponse)
{
	String timeNow;
	timeNow = TimeToStr(Now());
	Aresponse->Body->SetValue(
	    new TJSONString("WebProperties get method called at " + timeNow), True);
}

void TWebPropertiesResource1::GetItem(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse)
{
	String item;
	item = ARequest->Params->Values["item"];
	String timeNow;
	timeNow = TimeToStr(Now());
	AResponse->Bod->SetValue(
	    new TJSONString("WebProperties get method called at " + timeNow
	    + " item: " + item), True);
}

static void Register()
{
       	std::auto_ptr<TEMSResourceAttributes>
		  attributes(new TEMSResourceAttributes());
       	attributes->ResourceName = "WebProperties";
       	attributes->ResourceSuffix["GetItem"] = "{item}";
       	RegisterResource(__typeinfo(TWebPropertiesResource1),
		  attributes.release());
}

#pragma startup Register 32

Compile your RAD Server project and click the Open Browser button using localhost:<port#>/Content for the URL. This will bring up the index.html file in the browser.

Click the button to call the Get endpoint and see the result:

You can sign up for my RAD Server Embarcadero course to watch more than 3 hours of instruction, read the course notes and try the example projects. You’ll need an Enterprise, Architect or trial edition of RAD Server, Delphi or C++Builder.

Happy Programming!!!

David I.