The Complete Guide to Embarcadero RAD Server

Rapidly Design, Build, Debug and Deploy Services-Based Solutions Using RAD Studio and RAD Server

BY DAVID INTERSIMONE

An Idera, Inc. Company Table of Contents Chapter 1: Introduction...... 6 What You’ll Learn...... 6 RAD Server Overview...... 6 Building RAD Server based applications – Seven Key Aspects...... 8 Requirements for Building RAD Server Applications...... 9 Using the RAD Studio IDE...... 9 RAD Server Testing and Deployment Licenses...... 9 FireDAC Supported ...... 9 Deployment Platforms Supported...... 10 Web Servers Supported for Deployment...... 10 See Also...... 10 Chapter 2: Roundup of Core RAD Server Features...... 12 Core Features...... 12 Features Highlighted in the RAD Studio Feature Matrix...... 13 See Also...... 14 Chapter 3: Building Your First RAD Server Applications...... 16 Building REST-Based Services...... 16 Using the RAD Server Project Wizard...... 17 The Wizard Generated RAD Server Project and Source Code...... 20 Configuring RAD Server for your first Application...... 24 Testing your first RAD Server Application...... 29 Using the RAD Server Development Console...... 33 Using the RAD Server Console Ext JS Based UI...... 36 Using REST Debugger to Test RAD Server Applications...... 39 Enhancing the RAD Server App with FireDAC and InterBase...... 40 Create Client applications for the RAD Server application...... 44 See Also...... 46 Chapter 4: RAD Server Configuration File Explained...... 48 Main Sections of the Configuration File...... 48 Configuration [Data]...... 49 Authentication Configuration [Server.Keys]...... 50 Developer Server Connection [Server.Connection.Dev]...... 50 API Cross-Domain [Server.APICrossDomain]...... 51 Thread Management [Server.Threads.Dev]...... 51 Console Login [Console.Login]...... 52 Console Cookie Settings [Console.Cookies]...... 52 Console Display Options [Console.DisplayOptions]...... 52 Console Development Server Settings [Console.Connection.Dev]...... 52 Console Browser Settings [Console.Browser]...... 53 Console Development Paths Settings [Console.Paths.Dev]...... 53 Console ISAPI Paths Settings [Console.Paths.ISAPI]...... 53 Console Apache Paths Settings [Console.Paths.Apache]...... 53 Configuration Section for Extension Packages [Server.Packages]...... 53 Google Cloud Messaging [Server.Push.GCM]...... 54

2 (Copyright © 2019 Embarcadero Technologies, Inc.) Apple Push Notification Service [Server.Push.APNS]...... 54 Server Authorization Configuration Section [Server.Authorization]...... 54 Custom Resource Redirects [Server.Redirect]...... 55 Proxy Setup for Edge Module Requests [Server.EdgeHTTP]...... 56 Single/Multi Tenancy [Server.Tenants]...... 56 Specifying root paths [Server.Roots]...... 56 File Dispatching Support [Server.PublicPaths]...... 57 See Also...... 58 Chapter 5: Deploying a RAD Server Application to Windows and IIS...... 59 Step 1: Install InterBase 2017 with your RAD Server License...... 59 Step 2: Install IIS...... 65 Step 3: Create New Sites for RAD Server Engine and RAD Server Console...... 68 Step 4: Configure the EMSServer.ini file for the RAD Server Console...... 70 Step 5: Configuring IIS 7 for RAD Server ISAPI DLLs...... 70 Step 6: Enable ISAPI Modules...... 75 Step 7: Enable 32 bits ISAPI DLL on IIS 7 x64...... 77 Step 8: Configure IIS to Allow Cross Domain Requests...... 77 Step 9: Copy RAD Server application(s) and supporting files to the IIS production server...... 77 Step 10: Test RAD Server on the Windows Production Server...... 79 See Also...... 81 Chapter 6: Deploying a RAD Server application on Linux Apache...... 83 Prerequisites...... 83 Install InterBase 2017 for Linux...... 84 Starting InterBase on Linux...... 87 Running InterBase as a Service...... 88 RAD Server files for Linux support...... 89 RAD Server Stand-alone Installation...... 90 Setting Up RAD Server for Apache...... 95 Red Hat and related non-Debian distributions of Linux...... 95 Ubuntu and similar Debian distributions of Linux...... 96 Final Apache Server Setup and Restart...... 96 Test RAD Server Running on Apache...... 97 Apache is Ready for your RAD Server Packages...... 97 See Also...... 98 Chapter 7: Mapping Web Properties to Folders...... 100 A Simple Example...... 100 See Also...... 105 Chapter 8: Returning JSON using JSONValue and JSONWriter...... 106 Two Frameworks for Handling JSON Data...... 106 Using JSONValue...... 106 RAD Server App using JSONValue classes...... 107 VCL Client App using JSONValue classes...... 109 Using JSONWriter...... 111 A Simple JSONWriter Example...... 111 Using JSONWriter with a SQL Query...... 112 See Also...... 118 Chapter 9: Using FireDAC Batch Move and JSONWriter...... 119 Returning JSON Database Data Using a Memory Stream...... 119 Using FireDAC’s BatchMove, BatchMoveDataSetReader and BatchMoveJSONWriter...... 122

3 (Copyright © 2019 Embarcadero Technologies, Inc.) See Also...... 126 Chapter 10: Mapping Endpoints to Custom Method Names...... 127 Adding EndPointMethod Attributes...... 127 Test the RAD Server Application...... 129 See Also...... 130 Chapter 11: Mapping Endpoints to External Classes...... 131 Create the RAD Server package application...... 131 Test the RAD Server application...... 134 See Also...... 136 Chapter 12: Multiple Accept Types with EndpointProduce...... 137 A Simple Example...... 137 RAD Server Executes Methods Based on Accept Headers...... 139 See Also...... 143 Chapter 13: Using the EMSFileResource Component...... 144 Create RAD Server application package...... 144 Compile and Run the Application...... 146 See Also...... 148 Chapter 14: Using the EMSDataSetResource Component...... 149 Test the RAD Server application...... 152 Create VCL client application using the EMSDataSetResource endpoint functionality...... 154 See Also...... 157 Chapter 15: Putting it all together – Building a JavaScript client using Sencha Ext JS...... 158 Build an Employee Data RAD Server Application...... 158 Build and Test an EXT JS web client application using Sencha Architect...... 159 Step 1: Create and Preview the JavaScript Web Client App...... 160 Step 2: Test the Web Client’s Connection to RAD Server...... 168 Step 3: Setting up JSON Employee Data Object and Data Model...... 169 Step 4: Update the Web Client UI and Test the Final App...... 174 See Also...... 179 Chapter 16: Putting It All Together – Sample Walk Throughs...... 181 RAD Server Samples...... 181 FireDACResource...... 181 APIDocAttributes...... 184 ActiveDirectoryConsole...... 186 RAD Server Solution Series application templates...... 188 RAD Server Solution Series: Restaurant Survey Application...... 189 RAD Server Solution Series: Field Service Application...... 189 RAD Server Solution Series: Nurses Station Solution...... 190 See Also...... 190 Chapter 17: Summary...... 191 Sample Projects...... 191 Acknowledgments...... 191 Additional Resources...... 192 DocWiki Help and What’s New...... 192 Embarcadero Developer Community Blog Posts...... 192 RAD in Action: RAD Server by Cary Jensen...... 193 RAD Server Videos...... 193 Product Videos and Webinar Replays...... 193 RAD Server Field Service Application...... 194

4 (Copyright © 2019 Embarcadero Technologies, Inc.) RAD Server Application Deep Dive...... 195 RAD Studio Linux Development...... 195

5 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 1: Introduction

Chapter 1: Introduction

Today's computing landscape is no longer confined to a desktop, device, server, or data center. Applications are being moved from the desktop to multiple devices, network edge connections, and to on-premises, public and hybrid cloud services. With RAD Server and RAD Studio, you can build solutions that cover a wide spectrum of your company's (and customer’s) computing needs and business requirements.

This e-book will show you how to quickly design, build, debug, and deploy services-based multi-tier applications using RAD Server’s REST-based API hosting engine, components and technologies that are available in RAD Studio Enterprise and Architect editions.

The computers, software and devices used in creating this technical paper include RAD Studio 10.3.1 Rio Enterprise Edition, InterBase 2017 Server, Dell desktop running Windows version 10, Dell notebook running Windows version10, Dell notebook running Ubuntu version16.04 LTS, MacBook Pro running macOS 10.14 Mojave, iPhone running iOS version 12.1.4 and Nexus 7 running Android version 6.0.1

What You’ll Learn

After reading this e-book, you’ll have learned:

• RAD Server’s application development tips and techniques • RAD Server’s platform requirements • How to build and test your first RAD Server applications • How to deploy your RAD Server applications to Windows+IIS and Linux+Apache • New RAD Server features in RAD Studio 10.3.1 Rio • How to build client applications using , C++ and JavaScript to access your RAD Server endpoints • What samples and application templates are available for RAD Server to get you started • Where to find additional references, resources, videos, blog posts and more

RAD Server Overview

Embarcadero’s RAD Server provides a turn-key application foundation for rapidly building and deploying services-based applications using Delphi and C++Builder. RAD Server supports the REST (Representational State Transfer) protocol with JSON (or XML) parameter passing and return results. You can publish APIs, manage users and devices that are connected to the RAD Server, capture analytics about the use and users of applications, connect to local and enterprise databases using the FireDAC components and connect with Internet of Things (IoT) devices. RAD Server also supports user authentication, push notifications, geolocation, and data storage.

6 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 1: Introduction

Throughout the RAD Server documentation, source code, and in this technical paper, you’ll see references to EMS (Enterprise Mobility Services). EMS was the original name for the product, technologies, components and wizards that are now included the RAD Server product.

Figure 1: RAD Server: the Service Tier for a Multi-Tier Architecture

With RAD Server’s wizards, components, and tools you can quickly develop new middleware and back- end applications or migrate your existing Delphi and C++Builder client/server applications to a RAD Server based application to run on a server or in the cloud. You can publish your endpoints for REST calls from desktop, mobile, console, web and other types of applications. RAD Server comes with a full set of tools, components, database connectivity and interfaces that you will rely upon in building your service applications.

RAD Server applications can be deployed on top of Microsoft Windows IIS and Apache web servers, and you can deploy your Delphi-based services to Linux Intel 64-bit servers.

Figure 2: Develop and Test REST endpoints, Location Tracking and IoT Edgeware

7 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 1: Introduction

Building RAD Server based applications – Seven Key Aspects

To build RAD Server based applications, the diagram below guides developers through seven aspects and development phases.

Figure 3: Multi-Tier Development Made Easy

To start, create your server REST/JSON API-based endpoints (you can also use XML instead of JSON if required). Next extend the endpoints by integrating a wide range of databases, cloud services, IoT devices, and other technologies.

You can add more application endpoints to users and create API access control rules. You can write code that leverages RAD Server’s built-in secure data store to keep track of persistent data. You can create user groups, add users via console portal and import, or authenticate users via LDAP-based API services.

After you have developed and debugged your applications, you can host RAD Server applications on a private on-premises Windows and Linux servers. You can also migrate your applications to cloud systems like Amazon AWS, Microsoft Azure, Google, and other cloud providers.

After your application is put into production, you can manage access to your APIs, control users access, and analyze the utilization of your endpoint API activity with built-in application management interfaces. Finally, you can build desktop, mobile, Web, console, and other application types supported by RAD Studio. You can also build modern Web client applications using Sencha ExtJS’s set of components or use other tools and programming languages to build client applications that support your RAD Server application’s REST/JSON functionality.

8 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 1: Introduction

Requirements for Building RAD Server Applications

The following sections contain the product and technical requirements for building, testing, and deploying RAD Server applications. Unless otherwise noted, “RAD Studio” and the IDE apply to the RAD Studio, Delphi, and C++Builder products.

Using the RAD Studio IDE

A RAD Studio Enterprise or Architect Edition version 10.1 Berlin or later with a commercial license is required to build RAD Server applications. This white paper was written and tested using a commercial version RAD Studio version 10.3.1 Rio Enterprise Edition. The trial edition of RAD Studio Enterprise can be used for 30 days, for development and testing. The trial edition does not support deployment to a production server.

RAD Server Testing and Deployment Licenses

To test RAD Server applications, RAD Studio includes a 5-user developer license. Beginning with version 10.2 Release 2, RAD Server deployment licenses are included in Enterprise and Architect commercial editions of RAD Studio. These commercial editions include a single-site deployment license for RAD Server. RAD Studio 10.2.3 Architect edition includes a multi-site deployment license for customers who are on active Update Subscription.

RAD Server requires an InterBase 2017 encrypted database as part of deploying your applications in a Production Environment. You will need to use a valid RAD Server license to install this version of InterBase.

FireDAC Supported Databases

If your RAD Server application needs to connect with SQL databases, MongoDB, or through an ODBC database bridge, you can use FireDAC with the following database systems and versions.

Database Supported Versions Advantage Database Server 8.0 and higher Sybase SQL Anywhere 5.0.0 and higher IBM DB2 Server 8.1 and higher Firebird 1.5 and higher InterBase Server 6 and higher InterBase Lite / InterBase ToGo 6 and higher Informix Server 8 and higher. Client SDK v 3.5 and higher Microsoft Access Access 2000 ODBC driver v 4 from MDAC 2.8 and higher, Access 2007 ODBC driver v 12 and higher Microsoft SQL Server SQL Server 2000, ODBC driver from MDAC 2.8, SQL Server 2005,

9 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 1: Introduction

Database Supported Versions SQL Native Client 2005,SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017, SQL Azure, SQL Native Client 2008, LocalDB, SQL Native Client 2012 MySQL 3.21 and higher. MariaDB 10.3 Oracle 8.0.3 and higher PostgreSQL 7.4 and higher SQLite 3.0 and later Teradata 13 and higher MongoDB 3.0 and higher ODBC Data Source Level 2, 3 drivers

Deployment Platforms Supported

Windows 32/64 bit:

• Windows 10 • Windows 10 Anniversary Update • Windows 8.1 • Windows 7 SP1 • Windows Server 2012 and 2016

Linux / Intel 64-bit:

• Ubuntu Server (Ubuntu 14.04 LTS) • Ubuntu Server (Ubuntu 16.04 LTS) • Ubuntu Server (Ubuntu 18.04 LTS) • RedHat Enterprise Linux (version 7)

Web Servers Supported for Deployment

RAD Server applications have been tested using the following Web Server applications and platforms.

• Microsoft IIS Server for Windows – version 7 (Windows 32/64 bit) • Apache HTTP Server for Windows – versions 2.0, 2.2, and 2.4 (Windows 32/64 bit) • Apache HTTP Server for Linux – version 2.4

See Also For the latest updated information about installation of RAD Studio and deployment of RAD Server based applications please refer to the following Embarcadero DocWiki online links.

RAD Server Product Overview: https://www.embarcadero.com/products/rad-server

10 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 1: Introduction

RAD Studio Installation Notes: http://docwiki.embarcadero.com/RADStudio/Rio/en/Installation_Notes

RAD Studio and RAD Server Supported target platforms: http://docwiki.embarcadero.com/RADStudio/Rio/en/Supported_Target_Platforms

RAD Server Database Requirements for a Production Environment http://docwiki.embarcadero.com/RADStudio/Rio/en/ RAD_Server_Database_Requirements_for_a_Production_Environment_on_Windows

RAD Studio’s Platform Status Page: http://docwiki.embarcadero.com/PlatformStatus/en/Main_Page

RAD Server Pricing: https://www.embarcadero.com/products/rad-server#radserverpricing

InterBase: http://docwiki.embarcadero.com/RADStudio/Rio/en/InterBase

FireDAC: http://docwiki.embarcadero.com/RADStudio/Rio/en/FireDAC

FireDAC Supported Databases: http://docwiki.embarcadero.com/RADStudio/Rio/en/Databases_(FireDAC)

11 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 2: Roundup of Core RAD Server Features

Chapter 2: Roundup of Core RAD Server Features

RAD Server provides developers with a wide spectrum of features for building REST-based service applications. RAD Server (formerly known as EMS) was first introduced in RAD Studio version XE7. Since that first release enhancements and new capabilities have been added to address the needs of developers and add support for new platforms, architectures, and techniques.

Core Features

Here is a list of some of RAD Server’s core features that you’ll want to leverage in building your services- based applications.

• REST End Point Publishing – RAD Server implements a turn-key foundation for your application back end APIs and Services. RAD Server provides an easy to use API for publishing your business logic. Delphi or C++ code can be hosted as an API and auto-published as REST/JSON endpoints which are measured and managed by RAD Server. Endpoint publishing features include:

◦ Access Control – You can set up group and user level access, with authentication, to all application APIs and control who has access to your application’s API functionality. ◦ API Analytics – All REST API end-point activity is recorded and measured for robust statistics tracking and analytics. You can analyze user, API, and services activity daily, monthly, and yearly to gain insight into how your application is being utilized. You can also filter activity for all resources or by specific groups, users, device installations, and more. You can also export analytics to a CSV file for additional analysis with other tools. ◦ Desktop, Mobile & Web Client Applications – All C++ and Delphi code hosted on RAD Server is published as REST/JSON end points consumable by any client application on multiple platforms for extreme flexibility and future-proofing.

• Integration Middleware – RAD Server provides multiple integrations out of the box with connectivity to external servers, applications, databases, smart devices, cloud services, and other platforms. Integration capabilities include:

◦ Enterprise Data – RAD Server delivers high performance built-in connectivity to all popular Enterprise RDBMS servers. Database connectivity uses the FireDAC set of components and libraries for easy connectivity with data from a variety of sources. ◦ IoT Smart Device Connectivity – RAD Studio’s IoT components enable fast and easy integration of IoT Smart devices into your application’s services. RAD Server’s IoT Edgeware allows you to connect your Bluetooth IoT devices where they are physically located. ◦ Cloud Services – With RAD Server you can easily integrate REST cloud services from a variety of cloud, social, and BaaS platforms such as Google, Amazon, Facebook, Kinvey, and more.

• Application Services – RAD Server includes a collection of ready to use built-in services to power your application. RAD Server includes core functions such as user directory services and user

12 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 2: Roundup of Core RAD Server Features

management, push notifications, user location tracking, and built-in data storage. Some of these application and device services include:

◦ Push Notifications – Using RAD Server you can send programmatic or on-demand notifications to your application users and their devices. RAD Server currently supports push notification systems including Apple Push Notification service (APNs) and Google Cloud Messaging (GCM). You can also write custom code to connect with other push notification systems. ◦ Built-in Secure Datastore – With RAD Server’s support for secure an InterBase server’s encrypted datastore you can use built-in APIs to store and retrieve JSON data without requiring a separate database server. ◦ User/Group Management –Using RAD Server APIs you can create and manage your users, user groups, and control access via the RAD Server management portal. ◦ User Location/Proximity – Your RAD Server applications can leverage RAD Studio’s support for GPS, beacons, and beacon fence technology. RAD Server applications can track user movement, both indoors and outdoors, and respond to proximity events when users enter and exit custom beacon zones or approach designated beacon points.

Features Highlighted in the RAD Studio Feature Matrix

The following features are included in RAD Studio 10.3.x Rio. You’ll see notations for when some of the core features were introduced, enhanced, and those that are new in the Rio release.

• RAD Server is a turn-key REST-based middleware stack that includes API hosting, data access, and SQL Database access, with significantly optimized performance. RAD Studio version 10.3 Rio Enterprise Edition includes a single site RAD Server deployment license (additional RAD Server deployment licenses are available separately). RAD Studio version 10.3 Rio Architect Edition includes a multi-site deployment license. (Enhanced in 10.3 Rio) • Build, test and deploy RAD Server packages on Linux. Linux support is currently available for Delphi. (Introduced in 10.2 Tokyo) • Create custom REST APIs for your business functionality and map them to custom URIs. Use loadable packages for RAD Server. Integrate with FireDAC high-performance enterprise data access for Oracle, DB2, Microsoft SQL Server, Informix, MySQL Server, etc. • The new EndpointProduce attribute allows mapping of MIME types (from Accept HTTP request header) to GET endpoints; the new EndpointConsume attribute allows developers to map MIME types (from Content-Type HTTP request header) to PUT, POST, PATCH endpoints. These new features allow RAD Server applications to define two distinct ways to map methods to the same URL and HTTP verb, and return different types of data depending on the request. (New in 10.3 Rio) • HTTP Verb to Custom Method Name Mapping: Previous releases of RAD Server would generate custom mappings for HTTP verbs (GET, POST, etc.) to method names (this remains the default behavior). With RAD Server in v10.3 or later, you can also map an HTTP verb to a method with a custom name by using the new EndpointMethod attribute. (New in 10.3 Rio) • Delegate Processing of a Request to a Custom Class or Component. This feature allows for the sharing of response processing code. (New in 10.3 Rio)

13 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 2: Roundup of Core RAD Server Features

• New TEMSFileResource and TEMSDataSetResource components provide for extremely simplified implementations of RAD Server endpoints mapped to file system folders to access database tables and queries, including support for paging and sorting. (New in 10.3 Rio) • RAD Server multi-tenancy support and console app for managing multiple tenant configurations on Windows and Linux. With the Multi-Tenancy support, a single RAD Server instance with a single RAD Server database connection can support multiple isolated tenants. Each tenant has a unique set of RAD Server resources including Users, Groups, Installations, EdgeModules, and other data. (Introduced in 10.2 Tokyo) • RAD Server File Dispatching Support. (Introduced in 10.2 Tokyo) • RAD Server Console UI redesign and migration to the Ext JS library. Available for download in the GetIt Package Manager. (New in 10.3.1 Rio) • RAD Server Push Notifications server support for iOS and Android. • RAD Server’s EMSClientAPI component helps to simplify RAD Server client-side development. • User, groups, sessions, and API calls analytics and reporting using a web based interface using the EMS Console. (Enhanced in 10.2 Tokyo) • EMS client application to manage user accounts including a demo of how to synchronize RAD Server user accounts with ActiveDirectory users. (Enhanced in 10.2 Tokyo) • ThingPoint provides developers with an enterprise access point between remote gadgets and devices; a ThingPoint can locally store, filter, and compute vast amounts of IoT data collected at the edge, while ensuring only critical data is synced with the central repository via RAD Server. (Introduced in 10.1 Berlin) • Support for declaring and retrieving your RAD Server application’s metadata, based on the Swagger open API initiative (https://swagger.io/docs/specification/about/). This allows the use of a metadata language such as YAML or JSON for the representation of RAD Server REST APIs. (Introduced in 10.1 Berlin)

See Also

RAD Server Product Overview https://www.embarcadero.com/products/rad-server

RAD Studio RAD Server (EMS) http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_(EMS)

RAD Studio 10.3 Product Feature Matrix (PDF) https://www.embarcadero.com/docs/rad-studio-feature-matrix.pdf

Swagger Open API https://swagger.io/docs/specification/about/

RADServer Push Notifications http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_Push_Notifications

Apple Push Notification service (APNs) https://developer.apple.com/notifications/

14 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 2: Roundup of Core RAD Server Features

Firebase Cloud Messaging (FCM) <- Google Cloud Messaging (GCM) http://firebase.google.com/docs/cloud-messaging/

GCM migration guide https://developers.google.com/cloud-messaging/android/android-migrate-fcm

15 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Chapter 3: Building Your First RAD Server Applications

It’s time to start programming. In this chapter, you’ll learn how to build your first RAD Server based service applications using Delphi and C++Builder. Before you begin, make sure that your InterBase database server is running. To start InterBase, use the Windows Start Menu and click the InterBase Server Manager entry in the Embarcadero InterBase instance menu folder.

Figure 4: InterBase 2017 Server Manager.

RAD Server uses an InterBase database for the storage of user information, user groups, analytics, registered devices, version information, registered Edge Modules, push notification messages, and more.

Building REST-Based Services

RAD Server includes EMS (Enterprise Mobility Services) and offers a Mobile Enterprise Application Platform (MEAP) that you can host in a cloud or on-premises. Developers can use RAD Server to expose custom REST APIs and access enterprise database data using the FireDAC data access library and components.

RAD Server provides developers with a comprehensive solution that includes remote database access, user tracking, device application management, use analytics, and more. Compared to other solutions, RAD Server includes a pre-built application server that supports integration of custom packages. These custom packages can expose data sets, business logic, and other REST-based resources. Components are also available for mobile, web, and desktop application code to access RAD Server resources.

16 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 5: RAD Server REST API Architecture

Using the RAD Server Project Wizard

The fastest way to get started is to use the New Projects menu (File | New | Other…) and choose the RAD Server | RAD Server Package wizard for Delphi or C++Builder.

Figure 6: RAD Server Package Wizard choices for Delphi and C++.

Select the RAD Server Package project. A wizard will display to help create the starting project. On the first page choose how the wizard will create the resources and endpoints that will be included in the RAD Server application. The RAD Server Package Wizard provides two choices to proceed.

17 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Choice 1: Create an empty package that does not register a resource. Choose this option if you are going to add your resources later on. Using this choice, a package project will be created with a starting main library.

Figure 7: Create an empty RAD Server package.

Clicking the Finish button will create the starting project for additional development work to create the finished RAD Server application.

Choice 2: Create a package with a resource that extends the REST API of for the RAD Server. Click the Next Button and two additional wizard steps will display to help create the package project, resource, and endpoints. To build the first RAD Server project make this choice.

Figure 8: Create a resource based RAD Server package.

On the wizard’s second page set the Resource name to “Test”. The File type radio buttons presents two options: 1) create a unit for implementing the resource in code, and 2) create a data module for

18 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications implementing the resource using the IDE’s designer, components, and code editor. For this first RAD Server application choose to use a Data Module.

Figure 9: RAD Server Package Wizard page 2 - set the resource name and file type.

Click the Next button to create a starting set of endpoints.

Figure 10: RAD Server Package Wizard page 3 - choose starting EndPoints.

On the wizard’s third page choose from a set of predefined EndPoints: Get (REST GET), GetItem (REST GET with a segment at the end of the URL that identifies the item to get), Post (REST Post), PutItem (REST Put with a segment at the end of the URL that identifies the item to put), and DeleteItem (REST Delete with a segment at the end of the URL that identifies the item to delete). There is also a Select/deselect

19 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications all check box at the bottom of the EndPoints list. To create a package project with all of the EndPoints defined, click on all of the starting end-points or choose Select All. You can also step back through the wizard or click on the step links to make changes to the Package, Resource, and Endpoints screens. To create your starting project is to click the Finish button.

After the wizard completes, you are placed back in the IDE. The first thing to do is to save the project: • For the C++ and Delphi data module, use the name “MyDMUnit”. • For the C++ project and package use the name “MyFirstCppRADServerPackage”. • For the Delphi project and package use the name “MyFirstDelphiRADServerPackage”.

The Wizard Generated RAD Server Project and Source Code

Here are the projects and source code created by the wizard for Delphi and C++. For the C++ code, I have added a couple of lines of code in the Get and GetItem endpoint implementations to set the response (look for the // sample code comment line in MyDMUnit.cpp).

Delphi:

Figure 12: Generated Delphi resource Figure 11: Generated Delphi project. module.

MyFirstDelphiRADServerPackage.dpk: package MyFirstDelphiRADServerPackage; {$R *.res} {$IFDEF IMPLICITBUILDING This IFDEF should not be used by users} {$ALIGN 8} {$ASSERTIONS ON} {$BOOLEVAL OFF} {$DEBUGINFO OFF} {$EXTENDEDSYNTAX ON} {$IMPORTEDDATA ON} {$IOCHECKS ON} {$LOCALSYMBOLS ON} {$LONGSTRINGS ON} {$OPENSTRINGS ON} {$OPTIMIZATION OFF} {$OVERFLOWCHECKS OFF}

20 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

{$RANGECHECKS OFF} {$REFERENCEINFO ON} {$SAFEDIVIDE OFF} {$STACKFRAMES ON} {$TYPEDADDRESS OFF} {$VARSTRINGCHECKS ON} {$WRITEABLECONST OFF} {$MINENUMSIZE 1} {$IMAGEBASE $400000} {$DEFINE DEBUG} {$ENDIF IMPLICITBUILDING} {$RUNONLY} {$IMPLICITBUILD ON} requires rtl, emsserverapi; contains MyDMUnit in 'MyDMUnit.pas' {TestResource1: TDataModule}; end.

MyDMUnit.pas: unit MyDMUnit; // EMS Resource Module interface uses System.SysUtils, System.Classes, System.JSON, EMS.Services, EMS.ResourceAPI, EMS.ResourceTypes; type [ResourceName('Test')] TTestResource1 = 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); procedure Post(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); [ResourceSuffix('{item}')] procedure PutItem(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); [ResourceSuffix('{item}')] procedure DeleteItem(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); end; implementation {%CLASSGROUP 'System.Classes.TPersistent'} {$R *.dfm} procedure TTestResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); begin // Sample code AResponse.Body.SetValue(TJSONString.Create('Test'), True) end; procedure TTestResource1.GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

21 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications var LItem: string; begin LItem := ARequest.Params.Values['item']; // Sample code AResponse.Body.SetValue(TJSONString.Create('Test ' + LItem), True) end; procedure TTestResource1.Post(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); begin end; procedure TTestResource1.PutItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var LItem: string; begin LItem := ARequest.Params.Values['item']; end; procedure TTestResource1.DeleteItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var LItem: string; begin LItem := ARequest.Params.Values['item']; end; procedure Register; begin RegisterResource(TypeInfo(TTestResource1)); end; initialization Register; end.

C++:

Figure 14: Generated C++ resource Figure 13: Generated C++ project. module.

MyFirstCppRADServerPackage.cpp:

// EMS Package //------#include #pragma hdrstop

22 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

USEFORM("MyDMUnit.cpp", TestResource1); /* TDataModule: File Type */ //------#pragma package(smart_init) //------// Package source. //------#pragma argsused extern "C" int _libmain(unsigned long reason) { return 1; } //------

MyDMUnit.h:

// EMS Resource Modules //------#ifndef MyDMUnitH #define MyDMUnitH //------#include #include #include #include #include //------#pragma explicit_rtti methods (public) class TTestResource1 : public TDataModule { __published: private: public: __fastcall TTestResource1(TComponent* Owner); void Get(TEndpointContext* AContext, TEndpointRequest* Arequest, TEndpointResponse* AResponse); void GetItem(TEndpointContext* AContext, TEndpointRequest* Arequest, TEndpointResponse* AResponse); void Post(TEndpointContext* AContext, TEndpointRequest* Arequest, TEndpointResponse* AResponse); void PutItem(TEndpointContext* AContext, TEndpointRequest* Arequest, TEndpointResponse* AResponse); void DeleteItem(TEndpointContext* AContext, TEndpointRequest* Arequest, TEndpointResponse* AResponse); }; #endif

MyDMUnit.cpp:

//------#pragma hdrstop #include "MyDMUnit.h" #include //------#pragma package(smart_init) #pragma classgroup "System.Classes.TPersistent" #pragma resource "*.dfm" //------__fastcall TTestResource1::TTestResource1(TComponent* Owner) : TDataModule(Owner) { } void TTestResource1::Get(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse)

23 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

{ // Sample code AResponse->Body->SetValue(new TJSONString("Test"), True);} void TTestResource1::GetItem(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { String item; item = ARequest→Params→Values["item"]; // Sample code AResponse->Body->SetValue(new TJSONString("Test "+item), True); } void TTestResource1::Post(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { } void TTestResource1::PutItem(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { String item; item = ARequest->Params->Values["item"]; } void TTestResource1::DeleteItem(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { String item; item = ARequest->Params->Values["item"]; } static void Register() { std::auto_ptr attributes( new TEMSResourceAttributes()); attributes->ResourceName = "Test"; attributes->ResourceSuffix["GetItem"] = "{item}"; attributes->ResourceSuffix["PutItem"] = "{item}"; attributes->ResourceSuffix["DeleteItem"] = "{item}"; RegisterResource(__typeinfo(TTestResource1), attributes.release()); } #pragma startup Register 32

Configuring RAD Server for your first Application

Now that you’ve used the wizard to build your first RAD Server application, you can use the IDE to compile and test the application. The IDE uses the EMSDevServer as the host executable (EMDDevServer.exe) to start execution with the parameter being the package file to load. There are two versions of the EMSDevServer for Win32 and Win64 development ($(BDS)\bin\EMSDevServer.exe and $ (BDS)\bin64\EMSDevServer.exe).

24 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 15: Run | Parameters... dialog showing EMSDevServer.exe as the Host application.

RAD Studio also includes EMSDevConsole.exe which will start the EMSDevConsole server and open the EMS Console Server Window. The EMS Console provides a web application which displays analytics, provides for user/group management, and more for your RAD Server application.

Choose the Run | Run menu item or hit F9 to compile, link and run the starting application. The RAD Server Development Server will start, by default, using TCP port 8080. If this is the first time run of a RAD Server Application, a dialog box will display that says the RAD Server configuration file (emsserver.ini) was not found. This happens when there is no RAD Server registry key or if the configuration file does not exist.

Figure 16: Trying to start the RAD Server Development Server without a configuration file.

25 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Click the Yes button to run the RAD Server configuration wizard.

Figure 17: RAD Server setup wizard page 1 - specify the new EMS database connection parameters.

In the first wizard step, enter the InterBase server instance (by default RAD Studio’s development version of InterBase Server uses gds_db). If you previously installed InterBase using a different server instance name, enter that name string. This wizard page also contains the name for the RAD Server database (emsserver.ib), and directory that will contain the database and configuration file.

Click the Next button to tell the wizard whether you to create sample RAD Server database data for users and user groups. For development and testing we’ll set both check boxes.

Figure 18: RAD Server setup wizard page 2 - choose to generate sample data for the database.

26 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Click the Next button to set up the user name and password for logging into the RAD Server console.

Figure 19: RAD Server setup wizard page 2 - choose a Console user name and password.

Click the Next button to go to the final wizard step. The wizard is ready to create the RAD Server database file, configuration file, and set the Windows registry key for the currently logged in user.

Figure 20: Final RAD Server configuration wizard page.

This page displays the database file path and name, configuration path and name, and the Windows Registry key. You can always make changes to the RAD Server configuration file (emsserver.ini) at any time. Click the Finish button. A confirmation dialog will display with a reminder that the configuration will use an instance of InterBase that does not have a RAD Server license. The development license limits your RAD Server application to a maximum of 5 users.

27 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 21: Confirmation dialog box - using InterBase instance without a RAD Server license.

When you are ready to deploy your RAD Server application, you’ll be able to use your deployment licenses for RAD Server and InterBase.

Click the Yes button. The wizard will display the location of the emsserver.ini configuration file. It also lists the sample data that has been added to the database.

Figure 22: List of RAD Server files created by the configuration wizard.

Click the OK button. Two files now display in the C:\Users\Public\Documents\Embarcadero\EMS directory.

Figure 23: Files on disk created by the RAD Server configuration wizard.

Use InterBase’s IBConsole program to view the emsserver.ib database.

28 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 24: IBConsole view of the emsserver.ib database file.

Use RegEdit to view the registry key created for the RAD Server configuration file location.

Figure 25: RAD Server configuration file registry key.

Testing your first RAD Server Application

When the RAD Server configuration server is created, the RAD Server Development Server will start executing. On my development computer, the EMSDevServer reports that the default port (8080) is already in use because some other application (Tomcat Server, another web server, etc.) is already using the port 8080.

29 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 26: The RAD Server application cannot start because the default port is already in use.

To fix this problem, Click the OK button.

Figure 27: RAD Server Development Server not started due to port conflict.

You can use the edit box to enter an unused port number (I chose port 8087). Click the Start button and, if the new port number is unused, the RAD Server Development server will start running for this first launch.

To make the port change permanent for your all of your development work, edit the RAD Server development configuration file, emsserver.ini. Use a text editor to open the emsserver.ini file. Search for the [Server.Connection.Dev] section. Edit the unused port number and save the configuration file

[Server.Connection.Dev] Port=8087

The RAD Server configuration file will be covered in more detail in the chapter titled “RAD Server Configuration INI File Explained”.

When you click run in the IDE the RAD Server Development Server will start executing and the log will show the operations that take place for your package application.

C++ version:

30 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 28: RAD Server Development Server starting the first C++ application package.

Delphi version:

Figure 29: RAD Server Development Server starting the first Delphi application package.

The RAD Server Development Server log will display the configuration, database connection, licensing information, the application package that was loaded, the resources that were registered, and endpoints that were created.

Clicking the Open Browser button will start your default browser and display the JSON result of calling the GetVersion built-in endpoint. You’ve now used your first RAD Server REST endpoint!

31 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 30: Browser showing the output from calling the version endpoint.

In the browser, change the URL to localhost:8087/Test and hit enter. The browser will receive the JSON response from the Get endpoint.

Figure 31: Browser showing the JSON output from the Test resource's Get method.

If you pass an additional item on the URL, the GetItem endpoint will be called, and the code behind will return a JSON string containing the resource name plus the item you typed.

Figure 32: Browser showing the JSON output from the Test resource's GetItem method.

For simple examples it is okay to return a JSON string, but for larger, more complex data structures, you may not want to return a large JSON string. RAD Studio provides many other ways to generate JSON data including using JSON objects, JSON streams, and the JSON writer.

Edit the URL to use the “Users” resource which will call the default GetUsers endpoint to display JSON for the user generated by the RAD Server configuration wizard in the RAD Server datastore (there is only one to start).

32 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 33: JSON response in the Browser for a call to the GetUsers end point.

You’ve now used four of the endpoints that were generated by the RAD Server project wizard.

Using the RAD Server Development Console

Go back to the RAD Server Development Server and click the Open Console button. This will start the RAD Server Development Console Server.

Figure 34: RAD Server Development Console Server UI.

Click the Open Browser button to get the RAD Server Console home page.

33 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 35: RAD Server Console home page.

Click the Login link on the browser page and type your console username and password (Reminder: consoleuser and consolepass are the default values) in the sign in wizard.

Figure 36: RAD Server Console user sign in popup.

Type in the console username and password and click the Login button. The console’s overview page will display after logging in. The links on the left side of the page provide navigation to display and manage the users, groups, device installations, EdgeModules, Resources, and Analytics.

34 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 37: RAD Server Console overview page.

Click the Analytics drop down and select the API Calls analytic to see a chart of the daily, monthly, and yearly usage for the RAD Server application’s endpoints.

Figure 38: RAD Server Console API Calls Analytics page with usage chart and statistics.

35 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

All of this RAD Server application functionality is available after a wizard, a few menu choices, and mouse clicks that helped create a starting RAD Server application project. Run the RAD Server Development Server, set up your configuration file, and you can quickly test your application.

Using the RAD Server Console Ext JS Based UI

There is a new RAD Server Console UI for RAD Studio 10.3.1 that is built using Sencha’s Ext JS. This new console is available as a free download via RAD Studio’s GetIt Package Manager (use the Tools | GetIt Package Manager... menu item). Go to GetIt and search for RADServerConsole and you’ll see the following entry displays:

Figure 39: RAD Server Console Ext JS in the GetIt Package Manager.

Click the Install button and a description with a license agreement will display.

Figure 40: RAD Server Console Ext JS description and license agreement.

36 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Click the Agree all button. The RAD Server Console Ext JS version will be downloaded and installed.

Figure 41: RAD Server Console Ext JS downloaded and installed.

The console is installed in the folder at C:\Program Files (x86)\Embarcadero\Studio\20.0\ObjRepos\en\ EMS\extjs

Figure 42: RAD Server Console Ext JS files and folders.

Start the RAD Server application and click the Open Console button. Click the console’s Open Browser button. To launch the new Sencha EXT JS based console use the URL http://localhost:8081/extjs/index.html

Figure 43: RAD Server Console Ext JS user login screen.

Type in consoleuser and consolepass and click the LOGIN button.

37 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 44: RAD Server Console Ext JS home page.

After logging in you’ll see a fresher, graphics view of the RAD Server console single page JavaScript app with menu on the left and content on the right. The menu provides access and management of users, groups, device installations, EdgeModules, Resource Modules, and Analytics. Here is the screen that shows a list of users and their information including when the user was created and when the user information was last modified.

Figure 45: RAD Server Console Ext JS users table.

Clicking the Analytics menu item, a drop-down menu opens. You can select from a range of analytics including total users, active users, API calls, API endpoints called, and more. Analytics can be chosen by day, month, and year. The analytics can also be filtered by user, group, etc. Analytics results can also be saved to a CSV file for additional processing by external applications.

The following chart shows an API calls chart for a selected month.

38 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 46: RAD Server Console Ext JS API calls analytics page.

Using REST Debugger to Test RAD Server Applications

The REST Debugger, included with RAD Studio, is another way to test RAD Server application endpoints. Launch the REST Debugger from the IDE using the Tools | REST Debugger menu item. Use the GET method and URL http://localhost:8087/Users to see the JSON result.

Figure 47: REST Debugger test of the RAD Server application's GetUsers endpoint.

39 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Enhancing the RAD Server App with FireDAC and InterBase

You can add database functionality to the RAD Server application using FireDAC and an InterBase database in two ways: 1. add FireDAC database components to the existing RAD Server resource module 2. add an additional RAD Server resource module.

To keep the database functionality separate from the original endpoints, choose to add an additional server module to the project. With the first RAD Server application project loaded in the IDE, use the File | New | Other… menu item and select to add a new RAD Server Module to the existing Delphi and C++ projects.

Figure 48: Adding another RAD Server Module to the project.

Click the OK button and the RAD Server module wizard will display. Name the new Resource data module FireDAC and click the Next button.

Figure 49: RAD Server Module Wizard page 1 for the new resource.

40 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

For this RAD Server resource module choose to include the default Get and GetItem endpoints.

Figure 50: RAD Server Module Wizard page 2 - Get and GetItem.

Add a FireDAC FDConnection component to the resource module. Bring up the FDConnection connection editor with a right-mouse click on the component. Connect the FDConnection to the InterBase Employee.gdb sample database. Click the Test button to verify the connection.

Figure 51: FireDAC Connection Editor using the Employee.gdb database.

41 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Add an FDQuery component to the resource module. Right-mouse click on the component to bring up the Query editor. Type in the SQL statement “select * from customer” and click the Execute button to test the query.

Figure 52: FireDAC Query Editor - select * from customer.

Set the FDQuery component’s Name property to CustomerQuery. Add an FDSchemaAdapter component, set the Name property to CustomerSchemaAdapter, and set the CustomerQuery component’s SchemaAdpater property. Add a FDStanStorageJSONLink component.

You’re FireDAC resource module will now look something like the following figure:

Figure 53: FireDAC resource module with components.

Before you compile and run the application server, add a few FireDAC libraries to the Requires section of your project. Right-mouse click on the Requires section and choose the Add Reference… in menu item. Navigate to the C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\win32\release folder and multi- select the dbrtl, FireDAC, FireDACCommon, FireDACCommonDriver, and FireDACIBDriver files and click the OK button.

42 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 54: Delphi project Figure 55: C++ project with window with the required the rquired FireDAC FireDAC database libraries. database libraries.

Add the following code to implement the default Get endpoint for your FireDAC-based RAD Server resource. This code will provide a JSON version of query result to a browser or some other client application.

Delphi: procedure TFireDACResource1.Get(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var mStream : TMemoryStream; begin mStream := TMemoryStream.Create; CustomerQuery.Open(); FDSchemaAdapter1.SaveToStream(mStream, TFDStorageFormat.sfJSON); AResponse.Body.SetStream(mStream, 'application/json', true); end;

C++: void TFireDACResource1::Get(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { std::auto_ptr oStr(new TMemoryStream()); CustomerQuery->Open(); FDSchemaAdapter1->SaveToStream(oStr.get(), TFDStorageFormat::sfJSON); // Response owns stream AResponse->Body->SetStream(oStr.release(), "application/json", true); }

Compile and run the RAD Server application. Click the Open Browser button and test the new FireDAC resource module’s Get endpoint using the localhost:8087/FireDAC URL. The response from the Get endpoint will contain JSON from the SQL query.

43 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Figure 56: FireDAC resource Get endpoint returns JSON database information and data.

Create Client applications for the RAD Server application

First, add VCL and multi-device client applications to the project group. The client application will call the FireDAC resource’s GET endpoint (just as the browser did) to receive the query’s JSON response.

To add a new client project to the existing project group, right-mouse click on the project group and choose the Add New Project… in menu item. From the New Items dialog choose to create a VCL application and also a blank multi-device application. Follow the steps below for both the VCL and Multi- Device application projects.

Add an EMSPRovider component to connect each client application to the RAD Server application. Set the URLHost property to locahost. Set the URLPort property to 8087. Right-mouse click on the EMSProvider and choose the Test Connection pop-up menu item to make sure the client applications can connect to the RAD Server application.

Figure 57: Test the EMSProvider connection to the RAD Server application.

44 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

The dialog box that displays in the IDE contains the JSON returned by calling the RAD Server application’s version endpoint.

Add a BackendEndpoint component to allow the client application to access an endpoint in the RAD server application. Set the BackendEndpoint property name to BackendEndpointGetCustomers and set the Resource property to FireDAC. Add Button and Memo components to provide the minimal UI for the client application. The design window for your client application should look something like the following:

Figure 58: Client application UI with RAD Server application Provider and BackendEndpoint components.

Right-mouse click on the BackendEndpointGetCustomers component and choose the Execute menu item from the menu. If you’ve set up the EMSProvider and BackendEndpoint correctly you should see the following dialog window in the IDE.

Figure 59: Test result for the BackendEndpoint execution.

To complete the client application, add the following code to the OnClick event handler for the Button.

Delphi: procedure TForm2.Button1Click(Sender: TObject); begin BackendEndpointGetCustomers.Execute; Memo1.Lines.Clear; Memo1.Text := BackendEndpointGetCustomers.Response.JSONText; end;

45 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

C++: void __fastcall TForm1::Button1Click(TObject *Sender) { BackendEndpointGetCustomers->Execute(); Memo1->Lines->Clear(); Memo1->Text = BackendEndpointGetCustomers->Response->JSONText; }

Compile and Run the VCL and multi-device client applications and see the same JSON result that displayed in the browser.

Figure 60: RAD Server application JSON result for the Get endpoint call from the client application.

Congratulations! You have just built your first client application that connects to the RAD Server application. In the chapter titled “Using the EMSDataSetResource Component”, you’ll learn how to enhance your RAD Server applications using the new TEMSDataSetResource component. This new component provides additional flexibility in working with databases and data sets.

See Also

Code Samples created in this chapter: • DelphiFirstRADServerPackage • DelphiFirstRADServerPackageWithFireDAC • CppFirstRADServerPackage • CppFirstRADServerPackageWithFireDAC

RAD Server's Enterprise Mobility Services (EMS) http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_(EMS )

46 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 3: Building Your First RAD Server Applications

Setting Up Your RAD Studio Server Engine http://docwiki.embarcadero.com/RADStudio/Rio/en/Setting_Up_Your_RAD_Server_Engine

RAD Server Client Application http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_Client_Application

Configuring Your RAD Server Engine or RAD Server Console Server on Windows http://docwiki.embarcadero.com/RADStudio/Rio/en/ Configuring_Your_RAD_Server_Engine_or_RAD_Server_Console_on_Windows

RAD Server Administrative API http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_Administrative_API

New RAD Server Console Ext JS UI in RAD Studio 10.3.1 https://community.idera.com/developer-tools/b/blog/posts/new-rad-server-console-ext-js-ui-in-rad- studio-10-3-1

47 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

Chapter 4: RAD Server Configuration File Explained

The RAD Server configuration file, emsserver.ini, will be created by the configuration setup wizard if the file is not found when the IDE runs a RAD Server package project. You can also create the configuration file manually by starting with a template found in the C:\Program Files (x86)\Embarcadero\Studio\20.0\ ObjRepos\en\EMS folder.

The configuration setup wizard can also be executed as a standalone application. Open a command prompt or terminal window and type: EMSDevServer.exe -setup

EMSDevServer.exe can be found in:

• Windows 32-bit: C:\Program Files (x86)\Embarcadero\Studio\20.0\bin • Windows 64-bit: C:\Program Files (x86)\Embarcadero\Studio\20.0\bin64

After the configuration file is created, use the IDE or any text editor to make changes as needed.

Main Sections of the Configuration File

Each part of the RAD Server configuration file is defined by a section name string inside square brackets. The section names (in the order they are usually displayed) are:

• [Data] – RAD Server database instance name, database path, etc. • [Server.Limits] - Server Limits for maximum connections and users. • [Server.Keys] – Server authentication using MasterSecret, AppSecret and ApplicationID keys. • [Server.Connection.Dev] – Development server settings for the RAD Server’s port, HTTPS, CertFile, RootCertfile, KeyFile and KeyFile password. • [Server.APICrossDomain] – Contains a list of domains that can call server APIs. • [Server.Threads.Dev] - Controls how the EMSDevServer manages threads for incoming requests. • [Console.Login] – Contains the console username and password. • [Console.Cookies] – Settings for the user and console cookies. • [Console.DisplayOptions] – Set to enable the console’s EdgeModule menu items. • [Console.Connection.Dev] – Development server server settings for the RAD Server Console’s port, HTTPS, CertFile, RootCertfile, KeyFile and KeyFile password. • [Console.Browser] - Defines the console server settings for the number of rows and date format to display. • [Console.Paths.Dev] - Directories where the RAD Server Development Console will look for the Resource Files and Web Files. • [Console.Paths.ISAPI] - Directories where the Windows IIS RAD Server Console will look for Resource Files and Web Files. • [Console.Paths.Apache] - Directories where the Apache RAD Server Console will look for Resource Files and Web Files.

48 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

• [Server.Packages] - Specifies the path and description for extension packages you create to register custom resource endpoints. • [Server.Push.GCM] – Contains settings for Google Cloud Messaging (GCM). • [Server.Push.APNS] – Includes settings for Apple Push Notification Service (APNs). • [Server.Authorization] - Defines settings for the authorization requirements for the server application’s resources and endpoints. • [Server.Redirect] - Sets up redirects for custom resources to handle client application requests instead of the resource identified in the URL. • [Server.EdgeHTTP] - Set up a proxy host, port, username, and password for Edge Module based requests (if required). • [Server.Tenants] - Provides the settings for the single and multi tenant configurations for your RAD Server application. • [Server.Roots] - Allows for the setting of a root path string for the RAD Server application’s URLs. • [Server.PublicPaths] - Identifies the directories where static files are located and the URLs they are mapped to.

The following information explains more about the configuration file sections included in the RAD Server configuration file (emsserver.ini) that was created by the setup wizard.

Database Configuration [Data]

Use the Database Configuration section to modify the default information of the RAD Server Database that the RAD Server Application uses. Included in this section are the following:

• InstanceName – specifies the InterBase instance that hosts the RAD Server database. • Database – the RAD Server Database file local directory. • UserName – the user name to access the RAD Server Database. • Password – the password to access the RAD Server Database. • SEPassword – the password to connect to an encrypted InterBase database. • Pooled – enables FireDAC connection pooling to the RAD Server Database to reduce latency. • PooledMax – use this to set the maximum number of pooled connections allowed to the RAD Server Database.

[Data] ;# Interbase connection parameters InstanceName=gds_db Database=C:\Users\Public\Documents\Embarcadero\EMS\emsserver.ib UserName=sysdba Password=masterkey SEPassword= ;# SEPassword connects to an encrypted database Pooled= ;# Set Pooled=0 to disable connection pooled, Pooled=1 to enable. Default value is 1. PooledMax= ;# Set PooledMax=10 to limit maximum pooled connection. Default value is 50.

Server Limits [Server.Limits]

49 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

Use the Server Limits section to modify the default information of the number of simultaneous connections to the RAD Server database or the maximum number of RAD Server Users. This section includes:

• MaxConnections – the maximum number of concurrent HTTP requests to your RAD Server. • MaxUsers – the maximum number of RAD Server users allowed in the RAD Server Database. This value depends on the type of RAD Server license you have.

[Server.Limits] MaxConnections= ;# Set MaxConnections=10 to limit maximum concurrent HTTP requests. Default is 32. MaxUsers= ;# Set MaxUsers=3 to limit the number of users in the EMS database. This value is only used ;# when less than the maximum users permitted by the EMS run time license.

Authentication Configuration [Server.Keys]

The Authentication Configuration section allows modification of authentication for your RAD Server. This section includes:

• MasterSecret – this key authorizes any request to have complete access over all RAD Server Resources and all RAD Server data that is stored in the RAD Server Database. (update any user in the RAD Server Database, for example). • AppSecret – this key authorizes any request to access any authorized RAD Server Resource endpoints from a RAD Server based client application. • ApplicationID – the RAD Server will reject any request from a RAD Server based client application that does not match the ApplicationId. This identifier can be used to differentiate between your RAD Servers.

[Server.Keys] MasterSecret= ;# MasterSecret may be blank. If blank then the EMS server will not support ;# MasterSecret authentication. ;# HTTP 401 (Unauthorized) is raised if a request contains an incorrect MasterSecret AppSecret= ;# AppSecret may be blank. If AppSecret is not blank all requests must include the AppSecret. ;# HTTP 401 (Unauthorized) is raised if a request does not contain a correct AppSecret ApplicationID= ;# ApplicationID may be blank. If ApplicationID is not blank, all requests must include the ApplicationID. ;# HTTP 404 (not found) is raised if a request does not contain a correct ApplicationID

Developer Server Connection [Server.Connection.Dev]

The Developer Server Connection contains the default information for the connection to your RAD Server when used in developer mode. This section includes the following settings:

50 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

• Port – defines the connection port for the HTTP request to your RAD Server. • HTTPS - enables HTTPS support for your RAD Server. If enabled, you need to install OpenSSL, NSS, LibreSSL, or some other security library and configure the server certification file information. • CertFile – contains the absolute path to the self-signed certification file (.pem file). • RootCertFile – has the absolute path to the CA certification file (.pem file). If you use a self-signed certificate, leave this blank. • KeyFile – contains the absolute path to the self-signed key file (.pem file). • KeyFilePassword – contains the password set to use the certification file.

[Server.Connection.Dev] Port=8080 ;# The following options enable HTTPS support. ; HTTPS=1 ;# Set HTTPS=1 to enable HTTPS, HTTPS=0 to disable. ; CertFile= ; RootCertFile= ;# When using a self-signed certificate, RootCertFile is left blank. ; KeyFile= ; KeyFilePassword=

API Cross-Domain [Server.APICrossDomain]

Use this section to modify the permission to allow different domains (outside the RAD Server domain) to make HTTP requests to the public RAD Server API. This section includes:

CrossDomain – specify a list of domains that are allowed to make cross domain HTTP requests to the RAD Server API. To allow any domain, use the wildcard value *.

[Server.APICrossDomain] ;# Write here the domains allowed to call the API. Used for Cross-Domains ;# Set CrossDomain=* to allow access to any domain. CrossDomain=

Thread Management [Server.Threads.Dev]

Use the Server.Threads.Dev section of the configuration file to control how the EMSDevServer manages threads for incoming requests. Included in this section are:

• ThreadPool – set to one to enable the thread pool scheduler, zero to disable. • ThreadPoolSize – sets the number of threads that are available to handle requests. • ListenQueue – indicates how many requests can be queued when all threads in the pool are busy. • KeepAlive – set to one to enable HTTP connections to keep alive, set to zero to disable.

[Server.Threads.Dev] ;# The following options control how EMSDevServer manages threads to handle requests ;# ;# Thread pool options ; ThreadPool=1 ;# Set ThreadPool=1 to enable thread pool scheduler, ThreadPool=0 to disable. ; ThreadPoolSize=5 ;# ThreadPoolSize indicates how many threads are available to handle requests

51 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

;# ;# Queueing options ; ListenQueue=100 ;# ListenQueue indicates how many requests can be queued when all threads are busy ;# ;# Connection options ; KeepAlive=1 ;# Set KeepAlive=1 to enable HTTP connections to keep alive, KeepAlive=0 to disable.

Console Login [Console.Login]

The Console Login section defines the username and password for using the RAD Server console.

[Console.Login] UserName=consoleuser Password=consolepass

Console Cookie Settings [Console.Cookies]

This section defines the cookie names for the user and RAD Server console. These two settings can be left blank if cookies are not used.

[Console.Cookies] User= Console=

Console Display Options [Console.DisplayOptions]

This setting is used to enable the EdgeModules menu options in the Console UI.

[Console.DisplayOptions] ;# Set ShowEdgeModules=1 to enable EdgeModules menu options, ShowEdgeModules=0 to disable. ShowEdgeModules=1

Console Development Server Settings [Console.Connection.Dev]

This section contains connection settings for the RAD Server Console Server’s port, HTTPS, CertFile, RootCertfile, KeyFile, and KeyFile password

[Console.Connection.Dev] Port=8081 ;# The following options enable HTTPS support. ; HTTPS=1 ;# Set HTTPS=1 to enable HTTPS, HTTPS=0 to disable. ; CertFile= ; RootCertFile= ;# When using a self-signed certificate, RootCertFile is left blank. ; KeyFile= ; KeyPassword=

52 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

Console Browser Settings [Console.Browser]

This section contains settings for the number of rows and date format to display.

[Console.Browser] LimitRows=15 DateFormat=mm/dd/yy

Console Development Paths Settings [Console.Paths.Dev]

This section defines the path settings where the Development RAD Server Console will look for the Resource Files and Web Files.

[Console.Paths.Dev] ResourcesFiles=c:\program files (x86)\embarcadero\studio\20.0\ObjRepos\EN\EMS ; WebFiles= ;# When WebFiles is left blank, DevConsole will use ResourcesFiles as WebFiles path ;# If WebFiles is used the Web Server(e.g. IIS) should include in the HTTP-Response- Header 'Access-Control-Allow-Origin' to allow cross-domain request (e.g 'Access- Control-Allow-Origin: *')

Console ISAPI Paths Settings [Console.Paths.ISAPI]

This section defines the path settings where the IIS production RAD Server Console will look for the console’s Resource Files and Web Files.

[Console.Paths.ISAPI] ResourcesFiles= ; WebFiles= ;# When the webresources folder is in the same folder as the .dll, WebFiles is left blank, otherwise URL to the files (e.g. WebFiles=http://localhost ) ;# If WebFiles is used the Web Server (e.g. IIS) should include in the HTTP- Response-Header 'Access-Control-Allow-Origin' to allow cross-domain request (e.g 'Access-Control-Allow-Origin: *')

Console Apache Paths Settings [Console.Paths.Apache]

Use this section to define the directory path settings where the Apache production RAD Server Console will look for the console’s Resource Files and Web Files.

[Console.Paths.Apache] ResourcesFiles= ;WebFiles=

Configuration Section for Extension Packages [Server.Packages]

This section specifies the path and description for any extension packages you create to register custom resource endpoints.

[Server.Packages]

53 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

;# This section is for extension packages. ;# Extension packages are used to register custom resource endpoints ;c:\mypackages\basicextensions.bpl=mypackage description

Google Cloud Messaging [Server.Push.GCM]

This section is used to configure the Google Cloud Messaging (GCM) settings for your RAD Server application to support push notifications. In the EMSServer.ini file, go to the [Server.Push.GCM] section. There is one item in this section:

• APIKey: The API Key obtained when Setting Up the Messaging Service.

[Server.Push.GCM] ;# This section is for Google Cloud Messaging (GCM) settings. ;# These settings are needed to send push notifications to an Android device ApiKey=

Apple Push Notification Service [Server.Push.APNS]

Use this section to configure Apple Push Notification service (APNs) settings for the RAD Server application to support push notifications to Apple devices. This section includes the following settings:

• CertificateFileName – name of your Apple push notification certificate file (.p12 or .pem file). • CertificatePassword – contains the password for your certificate file if there is one. • ProductionEnvironment – this value tells whether the certificate has been created for a development or production environment.

[Server.Push.APNS] ;# This section is for Apple Push Notification Service (APNs). ;# These settings are needed to send push notifications to an iOS device CertificateFileName= ;# Name of .p12 or .pem file CertificateFilePassword= ;# Password of certificate file. Leave blank if file does not have a password. ProductionEnvironment= ;# Set ProductionEnvironment=1 when the certificate has been created for production. ;# Set ProductionEnvironment=0 when the certificate has been created for development. ;# Default value is 0 (development).

Server Authorization Configuration Section [Server.Authorization]

This section contains settings for the authorization requirements for the server application’s resources and endpoints. Authorization can be setup up based on built-in resources like Users and on custom resources that you create. Examples are included with their JSON attributes for Users and Resources.

[Server.Authorization] ;# This section is for setting authorization requirements for resources ;# and endpoints. ;# Authorization can be set on built-in resource (e.g.; Users) and on ;# custom resources.

54 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

;# Note that when MasterSecret authentication is used, these requirements ;# are ignored. ;# Resource settings apply to all endpoints in the resource. ;# Endpoint settings override the settings for the resource. ;# By default, all resource are public. ;# Settings are specified in JSON. ;# JSON attributes ;# {"public": true} - any client is authorized ;# {"public": false} - a client may be authorized depending on user or group. ;# user credentials (sessionid) must passed in the request ;# {"users": ["username1", "username2"]} - authorize a user by username. ;# {"users": ["userid1", "userid2"]} - authorize a user by userid. ;# {"users": ["*"]} - authorize any user. ;# {"groups": ["groupname1", "groupname2"]} - authorize a user in a user group. ;# {"groups": ["*"]} - authorize a user in any user group ;# ;# Examples ;# ;# Make all methods in the resource "Users" private except for LoginUser ;# and SignupUser endpoints ;Users={"public": false} ;Users.LoginUser={"public": true} ;Users.SignupUser={"public": true} ;# ;# Make all methods in the custom resource "Resource1" available to users ;# in group1 ;Resource1={"groups": ["group1"]} ;# ;# Make all methods in the custom resource "Resource2" available only ;# with MasterSecret authentication ;Resource2={"public": false} ;# ;# Special rules for user and group creators. ;# The creator of user is automatically authorized for the following endpoints: ;# Users.GetUser, Users.UpdateUser, Users.DeleteUser ;# The creator of a group is automatically authorized for the following endpoints: ;# Groups.GetGroup, Groups.UpdateGroup, Groups.DeleteGroup

Custom Resource Redirects [Server.Redirect]

This section allows you to set up redirects for custom resources to handle client application requests instead of the resource identified in the URL. Redirects may apply to all endpoints in a custom resource of to a specific endpoint. Examples are included to redirect all and specific endpoints.

[Server.Redirect] ;# This section is for setting resource redirects. ;# Redirects cause custom resources to handle a client request, rather than the ;# resource identified in the request URL. ;# A redirect may apply to all endpoints in a resource, or to a particular endpoint. ;# The destination resource must have an endpoint that handles the HTTP method (e.g.; GET, POST, PUT, DELETE) and URL segments of the ;# client request. Endpoint names are not used to resolve the destination endpoint. ;# Examples: ;# ;# Redirect all endpoints of the built-in resource "Users" to the custom resource "MyUsers" ;Users={"destination":"MyUsers"} ;# ;# Redirect specific endpoints to the custom resource "MyUsers" ;Users.LoginUser={"destination":"MyUsers"} ;Users.SignupUser={"destination":"MyUsers"}

55 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

Proxy Setup for Edge Module Requests [Server.EdgeHTTP]

This section sets up a proxy host, port, username, and password for Edge Module requests (if required).

[Server.EdgeHTTP] ;# Configure proxy for edge module requests ;ProxyHost=localhost ;ProxyPort=8888 ;ProxyUserName= ;ProxyPassword=

Single/Multi Tenancy [Server.Tenants]

This section provides the settings for tenant configurations for your RAD Server. You can select one of the following tenant modes: Single Tenant mode and Multi-Tenant mode.

In the EMSServer.ini file, go to the [Server.Tenants] section. Entries in this section include:

• MultiTenantMode: specifies the mode for your RAD Server. To switch to the Multi-Tenant mode, uncomment this line. If MultiTenantMode=1, the Multi-Tenancy is activated. If MultiTenantMode=0, RAD Server works in the Single Tenant mode. • DefaultTenantId: changes the default TenantId to the custom one in the Single Tenant mode. • TenantIdCookieName: specifies the custom cookie name to store the TenantId in RAD Server Console.

For more information about multi-tenancy, please see the RAD Server Multi-Tenancy Support docwiki topic.

[Server.Tenants] ;# This section defines settings for Single or Multi-Tenant modes. ;# ;# The MultiTenantMode option is used to turn on the Multi-Tenant mode. ;# If the Multi-Tenant mode is turned on, then TenantId and TenantSecret is required to access EMS Server. ;MultiTenantMode=1 ;# ;# Default Tenant is used only in the Single Tenant mode. ;DefaultTenantId=00000000-0000-0000-0000-000000000001 ;# ;# Define custom cookie name to store TenantId in EMS Console. ;TenantIDCookieName=TenantID

Specifying root paths [Server.Roots]

The Resources string setting defines a root path (prefix) for the RAD Server application’s URLs.

[Server.Roots] ;# This section is for specifying root paths ;# ;# Specifies the root path for resources ;Resources=API

56 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

Setting Resources=AshlandSoftware (or some other string), for example, defines that all RAD Server application URLs must be started with that string before the text of any resource strings. For example:

Using the http://localhost:8087/AshlandSoftware/version URL will return the RAD Server version JSON information.

Figure 61: Using the root path resources string and the version resource GetVersion endpoint.

Using the http://localhost:8087/AshlandSoftware/Test/HelloWorld URL will call the GetItem endpoint.

Figure 62: Using the root path resources string and the GetItem endpoint.

File Dispatching Support [Server.PublicPaths]

The Server.PublicPaths section is used to identify the directories where static files are located and defines a URL path. Each entry is defined as a JSON object and the number of entries is unlimited. In the EMSServer.ini file go to the [Server.PublicPaths] section. The properties of the JSON object include:

• path: The relative URL. • directory: Physical location of the static files. • default: Defines the default file that will be dispatched when browsing to the root of the virtual directory (optional). • mimes: Array of MIME file type masks(optional). • extensions: Array of file extensions (optional).

[Server.PublicPaths]

57 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 4: RAD Server Configuration File Explained

;# Identify directories that contain public files, such as .html ;# ;# The following entries define two different virtual directories ("images" and "content") ;# that may be used to access static files. The "directory" value indicates the physical ;# location of the static files. The optional "default" value indicates a file ;# that will be dispatched by default when browsing to the root of the virtual directory. ;# The optional "mimes" value is an array of MIME file type masks. And optional "extensions" ;# value is an array of file extensions. Only these files will be accessible from this directory. ;# The optional "charset" value specifies default charset for the files in the directory. ;Path1={"path": "images", "directory": "C:\\web\\images\\", "default": "index.html", "mimes": ["image/*"]} ;Path2={"path": "content", "directory": "C:\\web\\content\\", "default": "index.html", "extensions": ["js", "html", "css"], "charset": "utf-8"}

See Also

Configuring Your RAD Server Engine or RAD Server Console on Windows http://docwiki.embarcadero.com/RADStudio/Rio/en/ Configuring_Your_RAD_Server_Engine_or_RAD_Server_Console_on_Windows

Editing the Configuration of Your RAD Server EngineManually http://docwiki.embarcadero.com/RADStudio/Rio/en/ Editing_the_Configuration_of_Your_RAD_Server_Engine_Manually

RAD Server Multi-Tenancy Support http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_Multi-Tenancy_Support

RAD Server Console UI http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_Console_UI

RAD Server EdgeModules Resource http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_EdgeModules

58 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Chapter 5: Deploying a RAD Server Application to Windows and IIS

Previously, the first RAD Server applications were tested using the development versions of the RAD Server (EMSDevServer.exe) and Console (EMSDevConsole.exe) applications. This chapter covers how to set up Microsoft‘s Internet Information Services (IIS) along with the tools, run time libraries, InterBase server, package files, etc. required to deploy RAD Server applications in a Windows production environment.

For RAD Server applications to run on IIS, use the DLL versions of RAD Server Engine and RAD Server Console. These DLLs (EMSServer.dll and EMSConsole.dll) are located in the following RAD Studio folders:

• Windows 32 bits: C:\Program Files (x86)\Embarcadero\Studio\20.0\bin • Windows 64 bits: C:\Program Files (x86)\Embarcadero\Studio\20.0\bin64

Use the following steps to install Microsoft IIS 7, the RAD Server or Console, and InterBase 2017 server with a RAD Server license.

Step 1: Install InterBase 2017 with your RAD Server License

To run InterBase and your RAD Server application on the same machine or on a separate production machine you’ll need to install and register a new instance of InterBase 2017 using a valid RAD Server license (instead of the developer license that is included in RAD Studio) by following these steps:

1. Download the InterBase 2017 installer to your production computer. 2. Extract the .zip file to a new directory and run the install_windows.exe.

Figure 63: InterBase install setup program – Figure 64: Choose the InterBase 64-bit choose to install InterBase 2017. version to install.

59 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 65: Select to install both the Server and the Client.

Select Yes to install multiple instances of InterBase when:

• Installing InterBase 2017 on a computer with another InterBase instance. • Choosing a specific port and instance name for a first-time installation.

Figure 66: Install as multi-instance to control the port and instance name.

3. Choose the port number and instance name for InterBase to use. For example, port 3051 and RADServer.

60 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 67: Set the TCP Port number and Instance Name.

4. Set the destination folder of the RAD Server Interbase instance (for 64-bit Windows InterBase this will default to the C:\Program Files\Embarcadero\InterBase folder).

Figure 68: Choose the installation folder for InterBase 64-bit.

The installer asks you to review your choices:

61 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 69: Review the InterBase installation information before the install takes place.

If everything is okay, click the Install button.

5. Register the RAD Server InterBase instance with a valid RAD Server license.

Figure 70: Register using a valid RAD Figure 71: Registration is successful and the Server serial number. InterBase 2017 instance has been installed.

6. Start the RAD Server instance of InterBase 2017 server. Choose Start | Programs | Embarcadero InterBase 2017 | 64-bit instance = RADServer | InterBase Server Manager. If you want InterBase to run as a Windows service (the default) check that box. If you want InterBase to run when your computer starts, click the Automatic radio button. Then click the Start button.

62 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 72: InterBase Manager 64-bit for RADServer.

7. Follow these steps to prepare the production server to test and use the InterBase RAD Server instance and use EMSDevServer.EXE to create the RAD Server database and configuration file.

• Copy the 64-bit EMSDevServer.exe to the production server in a folder called c:\installs\ DevServerEXE • Copy the files in the RAD Studio Redist/win64 folder to the production server in a folder called c:\Redist • Edit the system path environment variable on the production server to add the c:\Redist and c:\Program Files\InterBase\bin folders.

Figure 73: Add two folders to your system path.

• Copy the RAD Server template and web resources files on the development computer from C:\Program Files (x86)\Embarcadero\Studio\20.0\ObjRepos\en\EMS to the production server

63 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

folder called c:\installs\ObjRepos\EMS (EMSDevServer.EXE will look for the template and web resource files in an ObjRepos\EMS subfolder under the same parent folder you place the EMSDevServer folder). • Make sure that the InterBase server with RAD Server license is started on the production server. • Copy the ibclient64.dll from the c:\Program Files\InterBase\bin to the c:\Windows\System32 folder.

8. Run the EMSDevServer.exe (as you did in the first RAD Server development configuration) to setup the production RAD Server configuration file and InterBase RAD Server database. The following screens show the steps:

Figure 74: RAD Server Setup Wizard - Set Figure 75: RAD Server Setup Wizard - Choose connection parameters for RAD Server. to generate sample data.

Figure 76: RAD Server Setup Wizard - Setup the Figure 77: RAD Server Setup Wizard - Review the console username and password. files and registry key that will be created.

64 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 78: RAD Server Setup Wizard - Figure 79: Windows Firewall - Allow access for Confirmation of the files that have been created. the RAD Server.

Figure 80: RAD Server Development Server is running.

The RAD Server wizard will create two files in the default folder under the Public Documents folder.

Figure 81: RAD Server Setup Wizard - Two files created in the Public Documents folder.

Step 2: Install IIS

65 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

To instal IIS, open the Windows Control Panel and under Programs and Features, click Turn Windows features on or off.

Figure 82: Use the Control Panel | Programs and Features | Windows Features to add IIS.

Next, expand the Internet Information Services node of the Windows Features dialog box and set the check boxes for the following IIS features:

• In Web Management Tools, check IIS Management Console. • In World Wide Web Services, expand the Application Development Features and then check ISAPI Extensions and ISAPI Filters. • In World Wide Web Services, expand the Common HTTP Features and make sure that Default Document, Directory Browsing, HTTP Errors, and Static Content are checked as well.

66 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 83: Select the IIS features required to support RAD Server.

When all of the required features have been selected, click the OK button to start the IIS installation. Depending on the speed of your computer, the installation will take approximately 3 minutes. During the installation, a folder named inetpub (containing several subfolders and files) is created as the starting point of the web server.

67 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 84: IIS is installed - c:\inetpub folder and sub- folders created.

After installing IIS 7, use a browser with the http://localhost/ URL to make sure IIS is running.

Figure 85: Test that IIS is installed and running.

Check your firewall settings and add, if necessary, an exception for port 80.

Step 3: Create New Sites for RAD Server Engine and RAD Server Console

68 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Create a wwwroot subfolder named RADServer. This subfolder will contain the RAD Server run time libraries and application package files. Create a wwwroot subfolder named RADConsole. This sub-folder will contain the RAD Server Console run time libraries and required web resources files.

Create a folder, c:\data, for the RAD Server Engine and RAD Server Console to share the RAD Server InterBase database. Copy the emsserver.ib file from C:\Public\Public Documents\Embarcadero\EMS to c:\data.

Copy the emsserver.ini file from C:\Public\Public Documents\Embarcadero\EMS to the C:\inetpub\ wwwroot\RADServer and C:\inetpub\wwwroot\RADConsole folders.

Copy the required binary files (either 32-bit or 64-bit) into the c:\inetpub\wwwroot\RADServer and RADConsole subfolders. You’ll find these files in a subfolder under your RAD Studio installation:

• 32-bit (C:\Program Files (x86)\Embarcadero\Studio\20.0\Redist\win32) • 64 bit (C:\Program Files (x86)\Embarcadero\Studio\20.0\Redist\win64)

To use RAD Server Engine with extension application packages, copy the following DLLs and package files (BPLs) to your c:\inetpub\wwwroot\RADServer subfolder:

If the application packages use FireDAC with a database management system other than InterBase, copy the additional FireDAC driver package files, such as FireDACSqliteDriver260.bpl for SQLite, to the wwwroot/RADServer sub-folder.

To use RAD Server console, copy the following DLLs and package files (BPLs) to your c:\inetpub\ wwwroot\RADConsole subfolder:

69 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Step 4: Configure the EMSServer.ini file for the RAD Server Console

To use the RAD Server console, copy the webresources folder from C:\Program Files (x86)\Embarcadero\ Studio\20.0\ObjRepos\en\EMS to c:\inetpub\wwwroot\RADConsole.

In the c:\inetpub\wwwroot\RADConsole folder edit the emsserver.ini file [Console.Paths.ISAPI] section to set up the ResourceFiles path.

[Console.Paths.ISAPI] ResourcesFiles=C:\inetpub\wwwroot\RADConsole WebFiles= ;# When the webresources folder is in the same folder as the .dll, WebFiles is left blank, otherwise URL to the files ( e.g.WebFiles=http://localhost ) ;# If WebFiles is used the Web Server (e.g. IIS) should include in the HTTP- Response-Header 'Access-Control-Allow-Origin' to allow cross-domain request (e.g 'Access-Control-Allow-Origin: *')

Whenever changes are made to emsserver.ini, restart the IIS server for the changes to take effect.

Step 5: Configuring IIS 7 for RAD Server ISAPI DLLs

The next step is configuring IIS so that the ISAPI DLLs for the RAD Server Engine (emsserver.dll) and RAD Server console (emsconsole.dll) can be used on your production server.

Open Internet Information Service Manager by using the Control Panel | System and Security | Administrative Tools (this operation requires Privileged mode). You can also type Inetmgr on the Windows Search programs and files to open the IIS Manager.

Figure 86: Open the IIS Manager.

Select the folder RADServer under Sites > Default Web Site.

70 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 87: IIS showing hte RADServer and RADConsole sites.

Right-click on the RADServer folder and select Convert to Application. This brings up the Add Application dialog box.

Figure 88: RADServer Convert to Application - Add Application.

Click the OK button.

Double-click Handler Mappings to open the Handler Mappings window.

71 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 89: Handler Mappings for the RADServer site.

Select ISAPI-dll (it appears grayed out). Click Edit from the Actions panel.

Figure 90: Handler Mappings - choose the Edit... action.

On the Executable (optional) field enter the path to the dll file and click the “…” open button and navigate to the RADServer subfolder where the emsserver.dll is located (or just type in the full path including the DLL name C:\inetpub\wwwroot\RADServer\emsserver.dll.

72 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 91: Edit Module Mapping for RADServer emsserver.dll.

Click OK. Then in the displayed dialog box click Yes.

Figure 92: Edit Module Mapping - confirm to allow this ISAPI extension.

Click the Edit Feature Permissions… in Actions panel for the RADServer site. The Edit Feature Permission dialog opens. Check Execute.

73 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 93: Edit Feature Permissions - check the Execute check box.

Click OK to commit the changes. You’ll see that ISAPI-dll has now been added to the Handler Mappings enabled list.

Figure 94: EMSServer ISAPI DLL is enabled for execution.

Follow the same IIS site setup steps for the RAD Server Console in the c:\inetpub\wwwroot\RADConsole folder. The ISAPI DLL to enable is emsconsole.dll.

74 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 95: EMSConsole ISAPI DLL is enabled for execution.

Step 6: Enable ISAPI Modules

Click the root node from the Connections tree. Double-click the ISAPI and CGI Restrictions icon.

Figure 96: IIS Root note - double click on the ISAPI and CGI Restrictions icon.

Click Edit Feature Settings … in the Actions panel. Check the Allow unspecified ISAPI modules option. This option allows any ISAPI dll to be executed under IIS.

75 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 97: IIS ISAPI and CGI Restrictions Edit Feature Settings

Click OK. See that the RAD Server Engine and RAD Server Console DLLs (in their separate folders) are allowed.

Figure 98: Make sure that RAD Server and RAD Server Console are allowed.

With the RADServer and RADConsole sites created and enabled for use, you can check the settings in the IIS applicationHost.config file at C:\Windows\System32\inetsrv\config\applicationHost.config

76 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Step 7: Enable 32 bits ISAPI DLL on IIS 7 x64

This step is only required if IIS x64 was installed and 32 bit ISAPI DLL support is required. Follow the next several steps to use 32-bit versions of RAD Server, RAD Server Console and application packages:

• Click the Application Pools node. • Click the DefaultAppPool item. • Click Advanced Settings from the Actions panel. • An Advanced Settings dialog opens. • Set Enable 32-bits Applications to True. • Click OK to commit the changes.

Step 8: Configure IIS to Allow Cross Domain Requests

To allow HTTP requests from different domains for a web server that is hosting the web file resources of RAD Server Console, set up the HTTP-Response-Header.

• Go to C:\inetpub\wwwroot and create a new folder, for example Web files folder. • Paste the web files resources folders under webfilesresources. • Note: You can not change the webresources folder name. • Open Internet Information Service Manager. • Select the Web files folder (webfilesresources) under Sites > Default Web Site. • Double-click HTTP Response Headers. • Click Add in the Actions panel. • Enter one of the following configurations (Name: Value): • Access-Control-Allow-Origin: * • (More restrictive option) Access-Control-Allow-Origin: http://domain:port/ • Click OK to commit the changes.

Step 9: Copy RAD Server application(s) and supporting files to the IIS production server

RAD Server application package files are compiled into folders depending on the project settings. The default Delphi package output and C++ final output directories are:

• For Delphi:

77 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

◦ 32-bit Windows – C:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl ◦ 64-bit Windows – C:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl\Win64 ◦ Linux – C:\Users\Public\Documents\Embarcadero\Studio\20.0\Bpl\Linux64 • For C++ all RAD Server application package files are compiled to the .\$(Platform)\$(Config) folders.

There are several ways to deploy the required RAD Server application and run-time DLL files to the production server. Three common transfer methods are:

• Copy the package files to the production server’s wwwroot/RADServer subfolder. • FTP the files to the production server. • Use the Platform Assistant (PAServer) with the Project | Deployment menu item to have the IDE move the files to the production server.

Figure 99: Project | Deployment files that PAServer can transfer.

Copy the Windows 64-bit compiled RAD Server extension package files (for example, MyFirstDelphiRADServerPackage.bpl) to the production IIS Server’s c:\inetput\wwwroot\RADServer folder.

On the Windows IIS server, the RADServer folder now contains the following files:

78 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 100: RADServer folder with dll. bpl files

Edit the emsserver.ini file to add each of your RAD Server extension packages under the [Server.Packages] section.

[Server.Packages] ;# This section is for extension packages. ;# Extension packages are used to register custom resource endpoints ;c:\mypackages\basicextensions.bpl=mypackage description c:\inetpub\wwwroot\RADServer\MyFirstDelphiRADServerPackage.bpl=First Test Demo

Step 10: Test RAD Server on the Windows Production Server

To make sure that the production IIS server and RAD Server are working, use the following URLs in your browser. http:///RADServer/emsserver.dll/version

Figure 101: Test that RAD Server is running under IIS.

Test a RAD Server extension package’s Get and GetItem methods:

79 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 102: Test the MyFirstDelphiRADServerPackage.bpl extension package’s test resource Get endpoint.

Figure 103: Test the MyFirstDelphiRADServerPackage.bpl extension package’s test resource Getitem endpoint.

Test the RAD Server Console Server on IIS:

Figure 104: RAD Server Console running on IIS - At login page.

Click the Login link, type in the console username and console password to get to the console home page.

80 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Figure 105: Console running on IIS - at the overview page.

Continue developing RAD Server package applications now that the production server is set up with IIS, InterBase, RAD Server Engine, and RAD Server Console. Copy the new (or updated) application BPL files along with any additional DLLs and BPLs required. Remember to keep the RAD Server configuration file (c:\wwwroot\radserver\emsserver.ini) [Server.Packages] section up to date.

See Also

Code Samples used in this chapter: • DelphiFirstRADServerPackage • CppFirstRADServerPackage

RAD Server Database Requirements for a Production Environment on Windows http://docwiki.embarcadero.com/RADStudio/Rio/en/ RAD_Server_Database_Requirements_for_a_Production_Environment_on_Windows

Installing the RAD Server or the RAD Server Console on a Production Environment on Windows http://docwiki.embarcadero.com/RADStudio/Rio/en/ Installing_the_RAD_Server_or_the_RAD_Server_Console_on_a_Production_Environment_on_Windows

Configuring Your RAD Server Engine or RAD Server Console Server on Windows http://docwiki.embarcadero.com/RADStudio/Rio/en/ Configuring_Your_RAD_Server_Engine_or_RAD_Server_Console_on_Windows

RAD Server Engine Authorization http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_Engine_Authorization

Tech Tip: How do I secure RAD Server for production deployment – by Eli M.

81 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS https://community.idera.com/developer-tools/b/blog/posts/tech-tip-how-do-i-secure-rad-server-for- production-deployment

InterBase Product Overview https://www.embarcadero.com/products/interbase

InterBase Documentation http://docwiki.embarcadero.com/RADStudio/Rio/en/InterBase

InterBase Installation, Registration, and Licensing Information http://docwiki.embarcadero.com/InterBase/2017/en/ Installation,_Registration,_and_Licensing_Information

InterBase Downloads https://downloads.embarcadero.com/free/interbase

Package Files Created by Compiling http://docwiki.embarcadero.com/RADStudio/Rio/en/Package_Files_Created_by_Compiling

82 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 5: Deploying a RAD Server Application to Windows and IIS

Chapter 6: Deploying a RAD Server application on Linux Apache

Deploying RAD Server and your applications to a Linux server provides the following options:

• To create a stand-alone RAD Server, see the RAD Server Stand-alone Installation section. • To create RAD Server for Apache, see the Setting Up RAD Server for Apache section.

Prerequisites

To configure RAD Server on Linux you need the following:

• RAD Studio version 10.3.1 Rio installed on a Windows development machine. • Linux machine or on a virtual machine. • Make sure you have Apache version 2.4 installed on your Linux machine. Note: For Ubuntu 16.04 LTS installations, the "libcurl3" package is required for RAD Server.

Figure 106: Checking the Apache version number.

Figure 107: Testing that Apache is running.

• Download InterBase 2017 Server from https://downloads.embarcadero.com/free/ibdev. Unzip the zip file and you’ll see the following files in the InterBase_2017_EN folder:

83 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Figure 108: InterBase 2017 installtion files and folders.

Install InterBase 2017 for Linux

In a terminal window, run the shell script installer for InterBase 2017 Server 64-bit on Linux.

Figure 109: Command line InterBase install.

Figure 110: Starting InterBase 2017 for Linux installation.

84 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Click the Next button.

Figure 111: Accept the License Agreement.

Accept the license agreement and click the Next button

Figure 112: Install the 64-bit edition.

Choose to install the 64-bit edition and click the Next button.

Figure 113: Choose to install the server and client files.

Choose to install the InterBase server and client, and click the Next button.

85 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Figure 114: Install as a multi- instance to choose the port and instance name.

Choose to install InterBase as a multi-instance. Set a specific TCP port number and Instance Name for RAD Server to use and click the Next button.

Figure 115: Set the port number and Instance Name as RADServer.

Review the installer choices and click the Install button.

Figure 116: Review the install choices.

86 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

The License Manager will display after the installation completes. Click on the Serial menu and choose the Add… menu item. In the dialog box that displays, enter your RAD Server Site License file for InterBase and click the Ok button.

Figure 117: Type in your InterBase RAD Server serial number.

Right-mouse click on the RAD Server key and choose the Register menu item from the menu.

Figure 118: Right mouse click on the RAD Server serial number and select Register.

Key in your Embarcadero account ID (or email) and password and click the Register button. If everything is correct, a successful Registration message will display.

Starting InterBase on Linux

Set the INTERBASE environment variable in the /etc/environment file.

INTERBASE=/opt/interbase

Confirm that the RADServer instance and port are defined in the /etc/Services file

Figure 119: RADServer instance and port in /etc/services.

To start the InterBase 2017 Server go to the bin directory for the directory created during the installation process: cd /opt/interbase/bin. Run the Server Manager as root: sudo ./ibmgr. Type start.

87 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Figure 120: Start the InterBase server.

Running InterBase as a Service

InterBase can also be set up as a service so that it runs when Linux is started. Use the following commands in a terminal window.

Copy the ibserverd script file to a version for the server instance you installed. In the InterBase installed examples directory: sudo cp ibserverd ibserverd_RADServer

Edit the ibserverd_RADServer script for the InterBase install location. Create a symbolic link for the libgds.so file to point to the libgds.so.0 version sudo ln -s /opt/interbase/lib/libgds.so.0 /usr/local/lib/libgds.so

Setup the automatic service launch by executing the above script as 'sudo' or 'root'. sudo ./ibservice.sh -s /opt/interbase RADServer

The 2nd argument is the install folder, and the 3rd argument is the instance name. When you restart the system, the service should start automatically as long InterBase is properly licensed.

Figure 121: Setting up InterBase to run as a service.

Check to make sure InterBase is set to start as a service on the next reboot or startup. ps -ef | grep ibserver

Figure 122: InterBase is set to start as a service.

When running InterBase as a service, the InterBase server starts automatically whenever the machine is running in a multi-user mode. To remove InterBase as a service, run:

88 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache sudo /opt/interbase/examples/ibservice.sh -r[emove]

RAD Server files for Linux support

The RAD Server files LinuxEMSServer.tar and ems_install.sh can be found in the following location in the RAD Studio folder: Linux 64-bit: C:\Program Files (x86)\Embarcadero\Studio\20.0\EMSServer

Figure 123: RAD Server install files in the RAD Studio directory.

Copy this folder and its two files to your Linux server.

The RAD Server installer on Linux consists of two files: • LinuxEMSServer.tar: the archive that includes servers, tools, packages, and static files. • ems_install.sh: the file that unpacks the files, places them into the required locations, and assigns attributes and rights.

LinuxEMSServer.tar includes the following: • Servers: ◦ server\EMSDevServerCommand (for Stand-alone server) ◦ server\libmod_emsserver.so (for Apache server support) ◦ server\EMSMultiTenantConsole (for RAD Studio Multi-Tenancy support) • Tools: ◦ EMSDevConsoleCommand (for Stand-alone server) ◦ server\libmod_emsconsole.so (for Apache server support) ◦ objrepos files needed by EMSDevConsoleCommand: ▪ objrepos\webresources ▪ objrepos\ems\EMSMSERVER.IB ▪ objrepos\ems\EMSMSERVER.SQL ▪ objrepos\ems\emsserver.ib ▪ objrepos\ems\emsserver.sql ▪ objrepos\ems\emsserver.ini • Packages needed by servers or tools: ◦ rtl\bplFireDACSqliteDriver260.so ◦ rtl\bplrtl260.so ◦ rtl\bplFireDACCommonDriver260.so ◦ rtl\bplFireDAC260.so ◦ rtl\bpldbrtl260.so

89 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

◦ rtl\bplFireDACIBDriver260.so ◦ rtl\bplFireDACCommon260.so ◦ rtl\bplxmlrtl260.so ◦ rtl\bplemsserverapi260.so

If the RAD Server application uses FireDAC with other database management systems besides InterBase, then FireDAC driver packages for those databases, such as bplFireDACSqliteDriver250.so for SQLite, will be needed.

RAD Server Engine uses the following default paths when you finish setting it up:

• EMSDevServerCommand, EMSDevConsoleCommand are located in /usr/lib/ems • mod_emsconsole, mod_emsserver is located in /usr/lib/apache2/modules (in case Apache is installed, if not the following location is used: in /usr/lib/ems) • ib, sql, ini and webresources folder are located in /etc/ems • RTL and DBRTL packages (*.so) are located in /usr/lib/ems

Also, the installer creates /var/emsserver_install.log.

RAD Server Stand-alone Installation

Ensure that libcurl3 is installed. To install it using the command: apt install libcurl3

Figure 124: Make sure libcurl3 is installed.

To install a stand-alone RAD Server, run the ems_install.sh shell script file.

Figure 125: Install RAD Server using sudo sh ./ems_install.sh

90 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

The install shell script will create a directory, /usr/lib/ems, containing the EMSDevServerCommand, EMSDevConsoleCommand along with several run time library (.so) files required for the command files to execute.

Figure 126: Directory and files created by the RAD Server install shell script.

Start the RAD Server stand-alone server: sudo ./EMSDevServerCommand -start. Starting the EMSDevServer for the first time will launch the RAD Server configuration wizard to help set up the emsserver.ini configuration file and emsserver.ib database file.

Figure 127: Starting RAD Server for the first time will create the configuration file.

Type y and enter to continue. Set the Server Instance to RADServer (or whatever the RAD Server InterBase instance name is called). For all of the other set up options press Enter. The configuration file wizard will review the configuration options.

91 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Figure 128: RAD Server configuration wizard options.

Type n if the configuration options are correct. The emsserver.ini and emsserver.ib files are created and RAD Server starts execution on port 8080. The configuration file can always be manually edited.

Figure 129: RAD Server configuration wizard creates the emsserver.ini and emsserver.ib files and starts running.

The RAD Server database file is in the /usr/lib/ems directory

Figure 130: RAD Server database file in /usr/lib/ems

92 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

The RAD Server configuration file is in the /etc/ems directory.

Figure 131: RAD Server configuration file in /etc/ems

Test the development RAD Server is working using a browser.

Figure 132: RAD Server test with Firefox.

Start the DevConsoleCommand (in /usr/lib/ems):

Figure 133: Start the RAD Server Console using the EMSDevConsoleCommand.

Test that RAD Server Console is working using a browser.

93 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Figure 134: Browser test that RAD Server Console is running.

Click the Login link and type in the console username and password (consoleuser, consolepass)

Figure 135: Logged in to the RAD Server Console.

To recap what has been done so far: • InterBase Server has been installed and started. • RAD Server has been installed. • The EMSDevServerCommand was started to run the configuration wizard that created the configuration file (emsserver.ini) and database file (emsserver.ib). • The development RAD Server Engine and RAD Server Console were tested using a browser.

After testing is complete, exit the EMSDevServer and EMSDevConsole.

EMSDevServerCommand and EMSDevConsoleCommand can be used for developing and testing Linux RAD Server applications without using Apache. The next step is to set up and test RAD Server and Delphi/C++ compiled application modules to run in production mode on Linux and Apache.

94 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Setting Up RAD Server for Apache

Use the InterBase iSQL command (in the /opt/interbase/bin directory) to make sure that RAD Server will be able to connect to the emsserver.ib database file. sudo ./isql -user sysdba -pass masterkey localhost/RADServer:/usr/lib/ems/emsserver.ib ISQL> SHOW VERSION; ISQL> SHOW DATABASE; ISQL> exit;

Figure 136: Using iSQL to test connectionto emsserver.ib database.

Configure the Apache HTTP Server to load the Apache RAD Server (libmod_emsserver.so) and Apache RAD Server Console (libmod_emsconsole.so) modules. Depending on which distribution of Linux you are deploying on, follow the steps below.

Red Hat and related non-Debian distributions of Linux

Edit Apache's httpd.conf file. Add the following lines to load the RAD Server Apache server module (libmod_emsserver.so) and the RAD Server Apache console module (libmod_emsconsole.so).

LoadModule emsserver_module /usr/lib/ems/libmod_emsserver.so LoadModule emsconsole_module /usr/lib/ems/libmod_emsconsole.so

Add the Location tags to create a container where you can specify access control rules for a given URL.

SetHandler libmod_emsserver-handler SetHandler libmod_emsconsole-handler

95 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Ubuntu and similar Debian distributions of Linux Create a new file called ems.load in Apache's mods-available directory to load the RAD Server Apache and console modules as needed.

LoadModule emsserver_module /usr/lib/ems/libmod_emsserver.so LoadModule emsconsole_module /usr/lib/ems/libmod_emsconsole.so

Create a new file called ems.conf in Apache's mods-available directory, to hold appropriate Location tags, used to specify access control rules for a given URL.

SetHandler libmod_emsserver-handler SetHandler libmod_emsconsole-handler

Review the contents of the two files just created.

Figure 137: Contents of ems.load

Figure 138: Contents of ems.conf

Enable the RAD Server modules using a2enmod: a2enmod ems

Figure 139: Using a2enmod to enable the RAD Server modules.

If there is a need to disable the RAD Server modules, use a2dismod: a2dismod ems

Final Apache Server Setup and Restart

Make sure that Apache can find the 64-bit SO file for InterBase. Create a symbolic link for the libgds.so file to point to the libgds.so.0 version

96 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

sudo ln -s /opt/interbase/lib/libgds.so.0 /usr/local/lib/libgds.so

Restart Apache Server as appropriate to your Linux distribution to load the newly configured RAD Server settings and modules.

Test RAD Server Running on Apache

To test that RAD Server is running correctly, use a browser to bring up the RAD Server version number.

Figure 140: RAD Server is running on Apache.

Apache is Ready for your RAD Server Packages

Build and test Delphi RAD Server applications on Windows. Change the target platform to Linux and build the Linux 64-bit version of the package file.

Copy the compiled resource module (e.g. bplMyFirstDelphiRADServerPackage.so) found in the C:\Users\ Public\Documents\Embarcadero\Studio\20.0\Bpl\Linux64 directory to the /usr/lib/ems directory on Linux.

Copy any required run-time libraries (the files that display in the Requires note of the project) to the /usr/lib/ems directory on Linux. The redistributable run time libraries for Linux are found in the C:\ Program Files (x86)\Embarcadero\Studio\20.0\Redist\linux64 directory.

The MyFirstDelphiRADServerPackage will need the additional run time libraries copied to the /usr/lib/ems directory

• bplrtl260.so • bplemsserverapi260.so

The /usr/lib/ems directory now contains the following files.

97 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache

Figure 141: Contents of the /usr/lib/ems directory.

Edit the /etc/ems/emsserver.ini file Server.Packages section and add the custom resource module.

[Server.Packages] ;# This section is for extension packages. ;# Extension packages are used to register custom resource endpoints /usr/lib/ems/bplMyFirstDelphiRADServerPackage.so=My Linux RAD Server package

Test the first Delphi RAD Server application package (compiled for 64-bit Linux) is running correctly with RAD Server + Apache using the URL: http://192.168.1.143/ems-server/test/Hello from Delphi for Linux

Figure 142: Delphi RAD Server package application running on Linux.

Now that the production Linux server is set up with RAD Server Engine and RAD Server Console, continue developing Delphi RAD Server package applications (stay tuned to the Embarcadero Road Map news for future support for C++). Copy the new (or updated) application package files along with any additional run time libraries that are required (the list will be found in the Requires node in the project manager). Remember to keep the RAD Server configuration file (/usr/lib/ems/emsserver.ini) [Server.Packages] section up to date.

See Also

Code Sample used in this chapter: • DelphiFirstRADServerPackage

Installing the RAD Server or the RAD Server Console on a Production Environment on Linux

98 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 6: Deploying a RAD Server application on Linux Apache http://docwiki.embarcadero.com/RADStudio/Rio/en/ Installing_the_RAD_Server_or_the_RAD_Server_Console_on_a_Production_Environment_on_Linux

Configuring Your RAD Server Engine or RAD Server Console Server on Linux http://docwiki.embarcadero.com/RADStudio/Rio/en/ Configuring_Your_RAD_Server_Engine_or_RAD_Server_Console_on_Linux

RAD Server Engine Authorization http://docwiki.embarcadero.com/RADStudio/Rio/en/RAD_Server_Engine_Authorization

Tech Tip: How do I secure RAD Server for production deployment – by Eli M. https://community.idera.com/developer-tools/b/blog/posts/tech-tip-how-do-i-secure-rad-server-for- production-deployment

InterBase Installation, Registration, and Licensing Information http://docwiki.embarcadero.com/InterBase/2017/en/ Installation,_Registration,_and_Licensing_Information

Running InterBase as a Service on Linux http://docwiki.embarcadero.com/InterBase/2017/en/ Installation,_Registration,_and_Licensing_Information#Linux

99 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 7: Mapping Web Properties to Folders

Chapter 7: Mapping Web Properties to Folders

RAD Server provides integration 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. The entries can include:

• path: The relative URL. • directory: Physical location of the static files. • default: Defines the default file that will be dispatched when browsing to the root of the virtual directory (optional). • mimes: Array of MIME file type masks(optional). • extensions: Array of file extensions (optional).

By default, the RAD Server configuration file will contain the following:

[Server.PublicPaths] ;# Identify directories that contain public files, such as .html ;# ;# The following entries define two different virtual directories ("images" and "content") ;# that may be used to access static files. The "directory" value indicates the physical ;# location of the static files. The optional "default" value indicates a file ;# that will be dispatched by default when browsing to the root of the virtual directory. ;# The optional "mimes" value is an array of MIME file type masks. And optional "extensions" ;# value is an array of file extensions. Only these files will be accessible from this directory. ;# The optional "charset" value specifies default charset for the files in the directory. ;Path1={"path": "images", "directory": "C:\\web\\images\\", "default": "index.html", "mimes": ["image/*"]} ;Path2={"path": "content", "directory": "C:\\web\\content\\", "default": "index.html", "extensions": ["js", "html", "css"], "charset": "utf-8"}

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.

A Simple Example

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

100 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 7: Mapping Web Properties to Folders

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:

RAD Server JS + Service

RAD Server GET method result will appear here

Choose Create package with resource from the RAD Server Package Wizard. Set the resource name to WebProperties and File type of Data Module. Select the Get and GetItem resource endpoints. Click the Finish button.

When the wizard finishes, the Delphi and C++ project files will look like the following:

Figure 143: Delphi WebProperties Figure 144: C++ WebProperties Demo project window. Demo project window.

Edit the code in the implementation of the Get and GetItem endpoints. The code for the RAD Server resource unit is as follows:

101 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 7: Mapping Web Properties to Folders

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 //------#pragma package(smart_init) #pragma classgroup "System.Classes.TPersistent" #pragma resource "*.dfm"

102 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 7: Mapping Web Properties to Folders

//------__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 attributes(new TEMSResourceAttributes()); attributes->ResourceName = "WebProperties"; attributes->ResourceSuffix["GetItem"] = "{item}"; RegisterResource(__typeinfo(TWebPropertiesResource1), attributes.release()); } #pragma startup Register 32

Run the RAD Server application. The “Public Path” entries show up in the RAD Server application log.

Figure 145: Web Properties Demo - RAD Server application log with public path entries.

Click the Open Browser button. Change the URL to localhost:8087/content to bring up the index.html file.

103 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 7: Mapping Web Properties to Folders

Figure 146: Browser displays the index.html file.

Click the Get RAD Server Content button to have the JavaScript code call the GET method and return the result.

Figure 147: Clicking the HTML button executes the Get method.

The RAD Server application’s log shows that the WebProperties Get method was executed.

Figure 148: Web Properties Demo - RAD Server application log shows the GET method executed by the HTML button click.

Chapter 12, Multiple Accept Types with EndpointProduce, contains another example that uses a [Server.PublicPaths] section path entry.

104 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 7: Mapping Web Properties to Folders

See Also

Code Samples created in this chapter: • DelphiWebPropertiesDemo • CppWebPropertiesDemo

RAD Server Engine File Dispatching Support http://docwiki.embarcadero.com/RADStudio/Rio/en/ Editing_the_Configuration_of_Your_RAD_Server_Engine_Manually#EMS_Server_File_Dispatching_Supp ort

Marco Cantu blog: RAD Server Support for Web Files in RAD Studio 10.2.3 http://blog.marcocantu.com/blog/2018-march-rad-server-files-10.2.3.html

105 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

Chapter 8: Returning JSON using JSONValue and JSONWriter

RAD Server provides support for handling JSON data that can be consumed by different programming languages and tools. Creating a JSON string, transmitting the string as a response, and having the client application code process the return is okay for smaller amounts of data. Imagine how large a JSON array response would be for an entire database or a complex data structure? RAD Studio provides two frameworks for working with JSON data. This chapter covers a few of the many ways RAD Server applications can return JSON to a calling application.

Two Frameworks for Handling JSON Data

RAD Studio provides two frameworks to handle JSON data:

• JSON Objects Framework – creates temporary objects to read and write JSON data. • Readers and Writers JSON Framework – allows you to read and write JSON data directly.

The JSON objects framework requires the creation of a temporary object to parse or generate JSON data. To read or write JSON data, you have to create an intermediate memory object such as TJSONObject, TJSONArray, or TJSONString before reading and writing the JSON.

The Readers and Writers JSON Framework, allows applications to read and write JSON data directly to a stream, without creating a temporary object. Not having to create a temporary object to read and write the JSON provides better performance and improved memory consumption.

Using JSONValue

Use the JSON Objects Framework to create JSON strings by assembling them in code. JSONValue is the ancestor class for all the JSON classes used for defining JSON string, object, array, number, Boolean, true, false, and null values. Included in the RAD Studio JSON implementation are the following classes and methods:

TJSONObject – implements a JSON object containing a collection of name/value pairs. Methods in TJSONObject Include:

• Parse – method to parse a JSON data stream and store the encountered JSON pairs into a TJSONObject instance. • ParseJSONValue – method to parse a byte array and create the corresponding JSON value from the data. • AddPair method – Adds a new JSON pair to a JSON object.

106 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

• GetPair method – Returns the key-value pair that has the specified I index in the list of pairs of a JSON object, or nil if the specified I index is out of bounds. • GetPairByName method – returns a key-value pair, from a JSON object, that has a key part matching the specified PairName string, or nil if there is no key matching PairName. • SetPairs – Defines the list of key-value pairs that this JSON object contains. • FindValue – Finds and returns a TJSONValue instance located at the specified Apath JSON path. Otherwise, returns nil. • Get Value – Returns the value part from a key-value pair specified by the Name key in a JSON object, or nil if there is no key that matches Name. • Pairs – Accesses the Key-value pair that is located at the specified Index in the list of pairs of the JSON object, or nil if the specified Index is out of bounds. • GetCount – Returns the number of key-value pairs of a JSON object.

TJSONArray – Implements a JSON array. JSONArray methods include:

• Add – Adds a non-null value given through the Element parameter to the current element list. • Get – Returns the element at the given index in the JSON array. • Pop – Removes the first element from the JSON array. • Size – Returns the size of the JSON array. • ToBytes – Serializes the current JSON array content into an array of bytes. • ToString – Serializes the current JSON array into a string and returns the resulting string.

Additional JSON classes include:

• TJSONString – Implements a JSON string. • TJSONNumber – Implements a JSON number. • TJSONBool – JSON Boolean value. • TJSONTrue – Implements a JSON true value. • TJSONFalse – Implements a JSON false value. • TJSONNull – Implements a JSON null value.

RAD Server App using JSONValue classes

The following RAD Server application implements a Get endpoint that uses several of the JSON classes to create, parse, and display the results of JSONObject, JSONArray and JSONValue.

Delphi: procedure TJSONValueDemoResource1.Get(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var JSONColor : TJSONObject; JSONArray : TJSONArray; JSONObject : TJSONObject; JSONValue : TJSONValue; begin // create some JSON objects JSONColor := TJSONObject.Create();

107 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

JSONColor.AddPair('name', 'red'); JSONColor.AddPair('hex', '#ff0000'); JSONColor.AddPair('name', 'blue'); JSONColor.AddPair('hex', '#0000FF'); JSONArray := TJSONArray.Create(); JSONArray.Add(JSONColor); JSONObject := TJSONObject.Create(); JSONObject.AddPair('colors', JSONArray); JSONValue := TJSONObject.Create(); JSONValue := TJSONObject.ParseJSONValue(JSONObject.ToJSON); AResponse.Body.SetValue( TJSONString.Create( JSONColor.ToJSON + ',' + JSONObject.ToJSON + ',{"name":"' + JSONValue.GetValue('colors[0].name') + '","hex":"'+ JSONValue.GetValue('colors[0].hex') + '"}' ), True); end;

C++: void TJSONValueDemoResource1::Get(TEndpointContext* AContext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { TJSONObject * JSONColor = new TJSONObject(); JSONColor->AddPair(new TJSONPair("name", "red")); JSONColor->AddPair(new TJSONPair("hex", "#ff0000")); JSONColor->AddPair(new TJSONPair("name", "blue")); JSONColor->AddPair(new TJSONPair("hex", "#0000FF")); TJSONArray * JSONArray = new TJSONArray(); JSONArray->Add(JSONColor); TJSONObject * JSONObject = new TJSONObject(); JSONObject->AddPair("colors", JSONArray); TJSONValue * JSONValue = new TJSONObject(); JSONValue = (TJSONObject*)TJSONObject::ParseJSONValue(JSONObject->ToJSON()); AResponse->Body->SetValue( new TJSONString( JSONColor->ToJSON() + "," + JSONObject->ToJSON() + ",{\"name\":\""+ JSONValue->GetValue("colors[0].name") + "\",\"hex\":\""+ JSONValue->GetValue("colors[0].hex") + "\"}" ),true); }

Figure 149: Browser output using JSONObject, JSONArray and JSONValue.

108 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

VCL Client App using JSONValue classes

The following VCL client application uses several of the JSONValue based classes to create, parse, and display the results of TJSONArray and TJSONObject based operations.

Delphi: unit MainUnit; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm2 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation uses JSON; {$R *.dfm} procedure TForm2.Button1Click(Sender: TObject); var JSONColor : TJSONObject; JSONArray : TJSONArray; JSONObject : TJSONObject; JSONValue : TJSONValue; mBoolean : boolean; begin mBoolean := true; JSONColor := TJSONObject.Create(); JSONColor.AddPair('name', 'red'); JSONColor.AddPair('hex', '#f00'); JSONColor.AddPair('mBoolean',TJSONBool.Create(mBoolean)); JSONArray := TJSONArray.Create(); JSONArray.Add(JSONColor); JSONObject := TJSONObject.Create(); JSONObject.AddPair('colors', JSONArray); JSONObject.AddPair('mBoolean',TJSONBool.Create(mBoolean)); Memo1.Lines.Clear(); Memo1.Lines.Add('JSONColor: '+JSONColor.ToJSON); Memo1.Lines.Add(''); Memo1.Lines.Add('JSONObject: '+JSONObject.ToJSON); Memo1.Lines.Add('');

109 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

JSONValue := TJSONObject.Create(); JSONValue := TJSONObject.ParseJSONValue(JSONObject.ToJSON); Memo1.Lines.Add('colors[0]'); Memo1.Lines.Add('name: '+ JSONValue.GetValue('colors[0].name')); Memo1.Lines.Add('hex: '+ JSONValue.GetValue('colors[0].hex')); Memo1.Lines.Add('mBoolean: '+JSONValue.GetValue('colors[0].mBoolean')); end;

C++: void __fastcall TForm1::Button1Click(TObject *Sender) { boolean mBoolean = true; TJSONObject * JSONColor = new TJSONObject(); JSONColor->AddPair(new TJSONPair("name", "red")); JSONColor->AddPair(new TJSONPair("hex", "#ff0000")); JSONColor->AddPair(new TJSONPair("name", "blue")); JSONColor->AddPair(new TJSONPair("hex", "#0000FF")); JSONColor->AddPair(new TJSONPair("mBoolean",new TJSONBool(mBoolean))); TJSONArray * JSONArray = new TJSONArray(); JSONArray->Add(JSONColor); TJSONObject * JSONObject = new TJSONObject(); JSONObject->AddPair("colors", JSONArray); Memo1->Lines->Clear(); Memo1->Lines->Add("JSONColor: "+JSONColor->ToJSON()); Memo1->Lines->Add(""); Memo1->Lines->Add("JSONObject: "+JSONObject->ToJSON()); Memo1->Lines->Add(""); TJSONValue * JSONValue = new TJSONObject(); JSONValue = (TJSONObject*)TJSONObject::ParseJSONValue(JSONObject->ToJSON()); Memo1->Lines->Add("colors[0]"); Memo1->Lines->Add("name: "+JSONValue->GetValue("colors[0].name")); Memo1->Lines->Add("hex: "+JSONValue->GetValue("colors[0].hex")); Memo1->Lines→Add( "mBoolean: "+JSONValue->GetValue("colors[0].mBoolean")); }

Figure 150: VCL Client App using JSON classes.

110 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

Using JSONWriter

Using JSONWriter simplifies RAD Server application development to craft custom JSON that delivers data for programming language clients to consume. Use JSONWriter to start your JSON object, write a property name and a value, and then keep writing properties and values until you finish the JSON object.

A Simple JSONWriter Example

Here is an implementation of a Get endpoint that returns data using JSONWriter’s WriteStartArray, WriteStartObject, WritePropertyName, WriteValue, WriteEndObject, WriteEndArray methods. Setting the JSONWriter.Formatting property value to Indented will produce a clean looking response in the Browser.

Delphi: implementation {%CLASSGROUP 'System.Classes.TPersistent'} uses System.JSON.Types; {$R *.dfm} procedure TEmployeeResource1.Get(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); begin // set the JSONWriter formatting to indented AResponse.Body.JSONWriter.Formatting := TJSONFormatting.Indented; // start the JSON Array AResponse.Body.JSONWriter.WriteStartArray; // start the JSON object AResponse.Body.JSONWriter.WriteStartObject; AResponse.Body.JSONWriter.WritePropertyName('Test'); AResponse.Body.JSONWriter.WriteValue('Foo bar'); // add WritePropertyName and WriteValue statements as often as needed // end the JSON object AResponse.Body.JSONWriter.WriteEndObject; // write as many additional JSON objects as you need // end the JSON array AResponse.Body.JSONWriter.WriteEndArray; end;

C++: void TSimpleJSONWriterResource1::Get(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { // set the JSONWriter formatting to indented AResponse->Body->JSONWriter->Formatting = TJsonFormatting::Indented;

111 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

// start the JSON Array AResponse->Body->JSONWriter->WriteStartArray(); // start the JSON object AResponse->Body->JSONWriter->WriteStartObject(); AResponse->Body->JSONWriter->WritePropertyName("Test"); AResponse->Body->JSONWriter->WriteValue("Foo bar"); // add WritePropertyName and WriteValue statements as often as needed // end the JSON object AResponse->Body->JSONWriter->WriteEndObject(); // write as many additional JSON objects as you need // end the JSON array AResponse→Body→JSONWriter→WriteEndArray(); }

Figure 151: JSON output with Formatting property set to Indented.

Using JSONWriter with a SQL Query

JSONWriter can also be used with rows and columns of database data. Create a RAD Server package application with Get and GetItem endpoints. Name the resource FireDAC. Add FDConnection, FDQuery, and FDStanStorageJSONLink components. Connect to the Employee.GDB InterBase database. Set the SQL property to select * from employee. The resource module should look like the following:

Figure 152: Resource module for using JSONWriter with a SQL Query.

112 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

Here are the Get and GetItem endpoint implementations to return custom JSON for a database query.

Delphi: interface uses System.SysUtils, System.Classes, System.JSON, EMS.Services, EMS.ResourceAPI, EMS.ResourceTypes, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.Phys.IB, FireDAC.Phys.IBDef, FireDAC.ConsoleUI.Wait, FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Stan.StorageJSON, Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, FireDAC.Comp.BatchMove.JSON, FireDAC.Comp.BatchMove, FireDAC.Comp.BatchMove.DataSet; type [ResourceName('FireDAC')] TFireDACResource1 = class(TDataModule) DatabaseConnection: TFDConnection; EmployeeQuery: TFDQuery; FDStanStorageJSONLink1: TFDStanStorageJSONLink; EmployeeQueryEMP_NO: TSmallintField; EmployeeQueryFIRST_NAME: TStringField; EmployeeQueryLAST_NAME: TStringField; EmployeeQueryPHONE_EXT: TStringField; EmployeeQueryHIRE_DATE: TSQLTimeStampField; EmployeeQueryDEPT_NO: TStringField; EmployeeQueryJOB_CODE: TStringField; EmployeeQueryJOB_GRADE: TSmallintField; EmployeeQueryJOB_COUNTRY: TStringField; EmployeeQuerySALARY: TFMTBCDField; EmployeeQueryFULL_NAME: TStringField; 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'} uses System.JSON.Types; {$R *.dfm} procedure TFireDACResource1.Get(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var RowCount,FieldIndex : integer; begin EmployeeQuery.Close(); EmployeeQuery.SQL.Clear(); EmployeeQuery.SQL.Add('select * from employee'); EmployeeQuery.Open(); // set the JSONWriter formatting to indented AResponse.Body.JSONWriter.Formatting := TJSONFormatting.Indented; // using JSONWriter to craft custom JSON return for all rows AResponse.Body.JSONWriter.WriteStartArray;

113 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

for RowCount := 0 to EmployeeQuery.RecordCount-1 do begin AResponse.Body.JSONWriter.WriteStartObject; for FieldIndex := 0 to EmployeeQuery.FieldCount-1 do begin Aresponse.Body.JSONWriter.WritePropertyName( EmployeeQuery.Fields[FieldIndex].FieldName); Aresponse.Body.JSONWriter.WriteValue( EmployeeQuery.FieldByName( EmployeeQuery.Fields[FieldIndex].FieldName).AsString) end; AResponse.Body.JSONWriter.WriteEndObject; EmployeeQuery.Next end; AResponse.Body.JSONWriter.WriteEndArray; end; procedure TFireDACResource1.GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var FieldIndex : integer; LItem : string; begin LItem := ARequest.Params.Values['item']; EmployeeQuery.Close(); EmployeeQuery.SQL.Clear(); EmployeeQuery.SQL.Add('select * from employee where EMP_NO = '+LItem); EmployeeQuery.Open(); // set the JSONWriter formatting to indented AResponse.Body.JSONWriter.Formatting := TJSONFormatting.Indented; // using JSONWriter to craft custom JSON return for the selected employee row AResponse.Body.JSONWriter.WriteStartObject; for FieldIndex := 0 to EmployeeQuery.FieldCount-1 do begin Aresponse.Body.JSONWriter.WritePropertyName( EmployeeQuery.Fields[FieldIndex].FieldName); Aresponse.Body.JSONWriter.WriteValue( EmployeeQuery.FieldByName( EmployeeQuery.Fields[FieldIndex].FieldName).AsString) end; end; procedure Register; begin RegisterResource(TypeInfo(TFireDACResource1)); end;

C++:

DMUnit.h

// EMS Resource Modules //------#ifndef DMUnitH #define DMUnitH //------#include #include #include #include #include #include #include #include

114 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //------#pragma explicit_rtti methods (public) class TFireDACResource1 : public TDataModule { __published: TFDConnection *EmployeeConnection; TFDStanStorageJSONLink *FDStanStorageJSONLink1; TFDQuery *EmployeeQuery; private: public: __fastcall TFireDACResource1(TComponent* Owner); void Get(TEndpointContext* AContext, TEndpointRequest* Arequest, TEndpointResponse* AResponse); void GetItem(TEndpointContext* AContext, TEndpointRequest* Arequest, TEndpointResponse* AResponse); }; #endif

DMUnit.cpp

//------#pragma hdrstop #include "DMUnit.h" #include //------#pragma package(smart_init) #pragma classgroup "System.Classes.TPersistent" #pragma resource "*.dfm" //------__fastcall TFireDACResource1::TFireDACResource1(TComponent* Owner) : TDataModule(Owner) { } void TFireDACResource1::Get(TEndpointContext* Acontext, TEndpointRequest* Arequest, TEndpointResponse* AResponse) { EmployeeQuery->Close(); EmployeeQuery->SQL->Clear(); EmployeeQuery->SQL->Add("select * from employee"); EmployeeQuery->Open(); // set the JSONWriter formatting to indented AResponse->Body->JSONWriter->Formatting = TJsonFormatting::Indented; // using JSONWriter to craft custom JSON return for all rows AResponse->Body->JSONWriter->WriteStartArray(); for (int RowCount = 0; RowCount < EmployeeQuery->RecordCount; RowCount++) { AResponse->Body->JSONWriter->WriteStartObject(); for (int FieldIndex = 0; FieldIndex < EmployeeQuery->FieldCount;

115 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

FieldIndex++) { AResponse->Body->JSONWriter->WritePropertyName( EmployeeQuery->Fields->Fields[FieldIndex]->FieldName); AResponse->Body->JSONWriter->WriteValue( EmployeeQuery->FieldByName( EmployeeQuery->Fields->Fields[FieldIndex] ->FieldName)->AsString); } AResponse->Body->JSONWriter->WriteEndObject(); EmployeeQuery->Next(); } AResponse->Body->JSONWriter->WriteEndArray(); } void TFireDACResource1::GetItem(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { String item; item = ARequest->Params->Values["item"]; EmployeeQuery->Close(); EmployeeQuery->SQL->Clear(); EmployeeQuery->SQL->Add("select * from employee where EMP_NO = "+item); EmployeeQuery->Open(); // set the JSONWriter formatting to indented AResponse->Body->JSONWriter->Formatting = TJsonFormatting::Indented; // using JSONWriter to craft custom JSON for the selected employee row for (int FieldIndex = 0; FieldIndex < EmployeeQuery->FieldCount; FieldIndex++) { AResponse->Body->JSONWriter->WritePropertyName( EmployeeQuery->Fields->Fields[FieldIndex]->FieldName); AResponse->Body->JSONWriter->WriteValue( EmployeeQuery->FieldByName( EmployeeQuery->Fields->Fields[FieldIndex] ->FieldName)->AsString); } } static void Register() { std::auto_ptr attributes( new TEMSResourceAttributes()); attributes->ResourceName = "FireDAC"; attributes->ResourceSuffix["GetItem"] = "{item}"; RegisterResource(__typeinfo(TFireDACResource1), attributes.release()); } #pragma startup Register 32

The JSON output of the Get and GetItem method calls display in the browser windows below.

116 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

Figure 153: JSON output for the Employee table’s rows and columns.

117 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 8: Returning JSON using JSONValue and JSONWriter

Figure 154: JSON output for a specific Employee.

See Also

Code Samples created in this chapter: • DelphiSimpleJSONWriter • DelphiJsonValueApp • DelphiFireDACJSONWriter • CppSimpleJSONWriter • CppJsonValueApp • CppFireDACJSONWriter

JSON http://docwiki.embarcadero.com/RADStudio/Rio/en/JSON

Readers and Writers JSON Framework http://docwiki.embarcadero.com/RADStudio/Rio/en/Readers_and_Writers_JSON_Framework

Tutorial: Using the REST Client Library to Access REST-based Web Services http://docwiki.embarcadero.com/RADStudio/Rio/en/ Tutorial:_Using_the_REST_Client_Library_to_Access_REST-based_Web_Services

118 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

Chapter 9: Using FireDAC Batch Move and JSONWriter

FireDAC components are available to produce and consume a stream containing database metadata and data encoded in JSON for a response from one of your RAD Server endpoints. Client applications that use languages, like JavaScript, could have a problem dealing with the database information and data that would be included in the response. RAD Studio provides a way to generate clean JSON that JavaScript or other languages would expect to receive.

Returning JSON Database Data Using a Memory Stream

FireDAC includes components to access a database table information and produce the result as a JSON string. Create a RAD Server application with a resource module. Add a FDConnection component and connect it with the InterBase sample Employee.gdb database. Add a FDTable component and set its Table property to the Employee table. Add a FDStanStorageJSONLink component to facilitate creating of the JSON.

Figure 155: RAD Server project's resource module.

When building a RAD Server Delphi based application, a set of warnings may display and a dialog box will emerge to allow the application package to be compatible with other installed packages.

119 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

Figure 156: Delphi project build dialog box for required packages.

Clicking the OK button will add the required package files to the requires section in the project. For C+ +Builder the required packages can be added manually (right-mouse click on the Requires node in the project manager window and select Add Reference… from the displayed menu).

Figure 157: Delphi RAD Server FireDAC Figure 158: C++ RAD Server FireDAC Memory Stream JSON project. Memory Stream JSON project.

120 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

Here is the RAD Server Get method implementation that uses a memory stream to send the JSON response with employee table data.

Delphi: procedure TEmpfiredacResource1.Get(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var mStream: TMemoryStream; begin mStream := TMemoryStream.Create; AResponse.Body.SetStream(mStream,'application/json', True); EmployeeTable.Open; EmployeeTable.SaveToStream(mStream, sfJSON); end;

C++: void TFireDACResource1::Get(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { TMemoryStream * mStream = new TMemoryStream; AResponse->Body->SetStream(mStream,"application/json", True); EmployeeTable->Open(); EmployeeTable->SaveToStream(mStream, sfJSON); }

Use a browser and the URL http://localhost:8087/FireDAC to get the response containing the JSON data for the database’s employee table. The JSON contains much more information than just the data. Also included in the response is metadata information about the table, columns, types, etc.

Figure 159: Browser window containing the JSON response.

This definitely is not the simple JSON column and value output that other languages could consume without parsing the response.

121 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

Using FireDAC’s BatchMove, BatchMoveDataSetReader and BatchMoveJSONWriter

For a complex database, using approaches like those mentioned in the previous chapter and above would involve writing a lot more code. Taking advantage of FireDAC’s FDBatchMove, FDBatchMoveDataSetReader, and FDBatchMoveJSONWriter components greatly simplifies the creation of the JSON response.

Use the RAD Server Package Wizard to create a new package project with Data Module Resource named BatchMove with a Get EndPoint. Add FireDAC FDConnection, FDQuery, FDBatchMove, FDBatcMoveDataSetReader, and FDBatchMoveJSONWriter components to the resource module. Rename the FDConnection as DatabaseConnection. Rename the FDQuery as CustomerQuery. Save the project.

Figure 160: Resource module with FireDAC Query, BatchMove, DataSetReader and JSONWriter.

Connect the DataBaseConnection component to the InterBase Employee.gdb sample database. Set the CustomerQuery SQL string to select * from customer. Set the FDBatchMoveDataSetReader’s DataSet property to CustomerQuery.

The code for the Get method can be simplified as follows:

Delphi: procedure TEmployeeResource1.Get(const AContext: TendpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); begin FDBatchMoveJSONWriter1.JsonWriter := AResponse.Body.JSONWriter; FDBatchMove1.Execute; end;

C++: void TEmployeeResource1::Get(TEndpointContext* Acontext,

122 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

TEndpointRequest* ARequest, TEndpointResponse* AResponse) { FDBatchMoveJSONWriter1->JsonWriter = AResponse->Body->JSONWriter; FDBatchMove1->Execute(); }

Before you compile and run the application server, you’ll need to add a few FireDAC libraries to the Requires section of your project. You’ll find these files in the C:\Program Files (x86)\Embarcadero\ Studio\20.0\lib for each of your target platforms.

Figure 161: Delphi BatchMove project. Figure 162: C++ BatchMove project.

Calling the GET method using the URL http://localhost:8087/BatchMove returns the JSON data result:

Figure 163: Browser with JSON result using BatchMove.

123 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

FDBatchMoveJSONWriter provides multiple options for formatting the JSON result. DataDef’s Formatting sub-property for TBatchMoveJSONWriter, by default, is set to None.

Figure 164: BatchMoveJSONWriter DataDef sub-properties in the Object Inspector.

Set the Formatting sub-property to Indented. Setting this sub-property will result in JSON responses that are laid out in a more readable form.

124 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

Figure 165: DataDef's Formatting sub-property set to Indented.

Re-run the RAD Server application. Use a browser to call the Get method (http://localhost:8087/BatchMove) and see the indent formatted JSON output.

Figure 166: Browser JSON result with Formatting set to Indented.

The FDBatchMove component also allows you to create mappings to setup source and destination columns mapping and to get the current source record values.

125 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

The Mappings property may be filled:

• Manually at design or run times. This allows to specify custom mappings, conversion expressions, etc. • Automatically at Execute call, if it is empty. The source and destination columns matching performed by the column names. If a destination column has no corresponding source column, then the destination column will be excluded from mapping and will be not filled at data movement.

See Also

Code Samples created in this chapter: • DelphiFireDACMemoryStreamJSON • DelphiFireDACBatchMove • CppFireDACMemoryStreamJSON • CppFireDACBatchMove

Marco Cantu blog: DataSet Mapping to JSON - RAD Server web service Delphi example http://blog.marcocantu.com/blog/2017-december-dataset-mapping-json.html

FireDAC.Comp.BatchMove.TFDBatchMove http://docwiki.embarcadero.com/Libraries/Rio/en/FireDAC.Comp.BatchMove.TFDBatchMove

FireDAC.Comp.BatchMove.JSON.TFDBatchMoveJSONWriter http://docwiki.embarcadero.com/Libraries/Rio/en/ FireDAC.Comp.BatchMove.JSON.TFDBatchMoveJSONWriter

Readers and Writers JSON Framework http://docwiki.embarcadero.com/RADStudio/Rio/en/Readers_and_Writers_JSON_Framework

FireDAC.TFDBatchMove Sample http://docwiki.embarcadero.com/CodeExamples/Rio/en/FireDAC.TFDBatchMove_Sample

RTL.JSONWriter http://docwiki.embarcadero.com/CodeExamples/Rio/en/RTL.JSONWriter

126 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 9: Using FireDAC Batch Move and JSONWriter

Chapter 10: Mapping Endpoints to Custom Method Names

In previous RAD Server releases, RAD Studio would generate method names that are similar to the service’s verbs (GET, POST, etc). This remains the default in RAD Studio 10.3.1 Rio. Starting with version 10.3 Rio, RAD Server applications can also map an HTTP verb to a method with a custom name using the EndpointMethod attribute. This chapter takes a simple RAD Server application and maps the REST GET verb to a different method name in the resource class. Adding EndPointMethod Attributes Use the RAD Server package project wizard to create a starting application package. Choose Create Package with resource. Set the Resource name to Test. Set the File type to Data Module. Select the Get and GetItem EndPoints.

Figure 167: RAD Server package wizard - Choose the Get and GetItem EndPoints.

Click the Finish button. After the project is created, rename the declaration and implementation of the Get and GetItem methods to TestGet and TestItem. For Delphi, add EndPointMethod attributes before the renamed methods. For C++, in the register function, add Attribute->EndPointMethod assignment statements for the renamed methods. The declaration and implementation source code should look like the following.

Delphi:

[ResourceName('Test')] TTestResource1 = class(TDataModule) published [EndpointMethod(TEndpointRequest.TMethod.Get)] procedure TestGet(const AContext: TendpointContext; const ARequest: TendpointRequest; const AResponse: TEndpointResponse); [EndpointMethod(TEndpointRequest.TMethod.Get)] [ResourceSuffix('{item}')] procedure TestItem(const AContext: TendpointContext; const ARequest: TendpointRequest; const AResponse: TEndpointResponse);

127 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 10: Mapping Endpoints to Custom Method Names end; procedure TTestResource1.TestGet(const AContext: TendpointContext; const ARequest: TendpointRequest; const AResponse: TEndpointResponse); begin // Sample code AResponse.Body.SetValue(TJSONString.Create('Test Get Method'), True) end; procedure TTestResource1.TestItem(const AContext: TendpointContext; const ARequest: TendpointRequest; const AResponse: TEndpointResponse); var LItem: string; begin LItem := ARequest.Params.Values['item']; // Sample code Aresponse.Body.SetValue(TJSONString.Create('Test Item Method: ' + LItem), True) end;

C++:

ServerUnit.h

// EMS Resource Modules //------#ifndef ServerUnitH #define ServerUnitH //------#include #include #include #include #include //------#pragma explicit_rtti methods (public) class TTestResource1 : public TDataModule { __published: private: public: __fastcall TTestResource1(TComponent* Owner); void TestGet(TEndpointContext* AContext, TEndpointRequest* Arequest, TEndpointResponse* AResponse); void TestItem(TEndpointContext* AContext, TendpointRequest* Arequest, TEndpointResponse* AResponse); }; #endif

ServerUnit.cpp

//------#pragma hdrstop #include "ServerUnit.h" #include //------#pragma package(smart_init) #pragma classgroup "System.Classes.TPersistent" #pragma resource "*.dfm"

128 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 10: Mapping Endpoints to Custom Method Names

//------__fastcall TTestResource1::TTestResource1(TComponent* Owner) : TDataModule(Owner) { } void TTestResource1::TestGet(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { AResponse->Body->SetValue(new TJSONString("Test Get Method"), True); } void TTestResource1::TestItem(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { String item; item = ARequest->Params->Values["item"]; AResponse->Body->SetValue(new TJSONString("Test Item Method: "+item), True); } static void Register() { // wizard creates: std::auto_ptr // attributes(new TEMSResourceAttributes()); // For C++11 Win32 classic & Win64 compatible use: std::unique_ptr attributes(new TEMSResourceAttributes()); // For C++17, Win32 use: // auto attributes = make_unique(); attributes->ResourceName = "Test"; attributes->EndPointHTTPMethod["TestGet"] = TEndpointRequest::TMethod::Get; attributes->ResourceSuffix["TestItem"] = "{item}"; attributes->EndPointHTTPMethod["TestItem"] = TEndpointRequest::TMethod::Get; RegisterResource(__typeinfo(TTestResource1), attributes.release()); } #pragma startup Register 32

Test the RAD Server Application

Run the example RAD Server App. Note that the new endpoint names for the Test resource display in the RAD Server log.

Figure 168: RAD Server application log showing the renamed Endpoints.

129 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 10: Mapping Endpoints to Custom Method Names

Use the http://localhost:8087/Test URL to execute the Get EndPoint (now called TestGet).

Figure 169: Browser result showing the execution of the TestGet method.

Use the http://localhost:8087/Test/HelloWorld URL to execute the GetItem EndPoint (now called TestItem).

Figure 170: Browser result showing the execution of the TestItem method.

The new EndpointMethod attribute allows for the creation of self-describing names for the REST HTTP verbs in your application server methods. This new feature can also help with the documentation and implementation of client, web and service applications that call into the RAD Server application.

See Also

Code Samples created in this chapter: • DelphiRADServerCustomMethodName • CppRADServerCustomMethodName

HTTP Verb to Custom Method Name Mapping http://docwiki.embarcadero.com/RADStudio/Rio/en/ RAD_Server_Enhanced_URL_Mapping#HTTP_Verb_to_Custom_Method_Name_Mapping

130 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 11: Mapping Endpoints to External Classes

Chapter 11: Mapping Endpoints to External Classes

RAD Studio 10.3.1 adds the ability for the RAD Server custom resources API to delegate request processing to resource module Delphi fields, which are custom endpoint publisher classes / components.

Request processing may be delegated to a resource module field of object type. The object type may be any class (including TComponent descendant), implementing IEMSEndpointPublisher interface. A class is called the endpoint publisher class. By default, all class endpoints will get resource suffix equal to resource module field name. This may be overridden by specifying attribute for resource module field:

• ResourceName – to override field name. • ResourceSuffix – to override resource suffix.

A class endpoint may be marked with ResourceSuffix attribute. When suffix starts with "./", then specified suffix will be appended to default resource suffix of resource module field. Any attribute specified for a resource module endpoint can be specified for a class endpoint. An attribute can be specified at one of the places in order of priority (less priority at beginning of the list, higher priority overrides lower priority attribute):

• Class endpoint • Resource module field. An attribute first argument may be a class endpoint name. • TEMSResourceAttributes specified at resource module registration. A name used for TEMSResourceAttributes calls is a .. Create the RAD Server package application Use the RAD Server package wizard to create a package and resource module. Name the resource Test and choose to add all of the endpoints.

Delphi:

Figure 171: RAD Server application project.

131 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 11: Mapping Endpoints to External Classes

Create a component class, TEmpsProvider, that inherits from the IEMSEndpointPublisher interface. Create the declaration along with ResourceSuffix(s) and implementation for the TEmpsProvider endpoints. Add a class var to hold the JSONArray. In the public section of the Test resource add a declaration for the TEmpsProvider. Use the following code for the interface and implementation sections. The Interface declaration for TEmpsProvider and the Test resource: interface uses System.SysUtils, System.Classes, System.JSON, EMS.Services, EMS.ResourceAPI, EMS.ResourceTypes; type TEmpsProvider = class(TComponent, IEMSEndpointPublisher) private class var FArray: TJSONArray; private function GetItemByID(ARequest: TEndpointRequest): Integer; class constructor Create; class destructor Destroy; public procedure Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); overload; [ResourceSuffix('./{id}')] procedure GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); overload; [ResourceSuffix('./{id}')] procedure Put(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); procedure Post(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); [ResourceSuffix('./{id}')] procedure Delete(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); end; [ResourceName('Test')] TTestResource = class(TDataModule) public Emps: TEmpsProvider; constructor Create(AOwner: TComponent); override; end;

Implementation for TEmpsProvider and the Test resource: uses System.JSON.Builders, System.JSON.Writers, System.JSON.Readers; procedure Register; begin RegisterResource(TypeInfo(TTestResource)); end; { TEmpsProvider } class constructor TEmpsProvider.Create;

132 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 11: Mapping Endpoints to External Classes var oWriter: TJsonObjectWriter; oBuilder: TJSONArrayBuilder; begin oWriter := TJsonObjectWriter.Create(False); oBuilder := TJSONArrayBuilder.Create(oWriter); try oBuilder.BeginArray .BeginObject .Add('id', '1') .Add('first_name', 'John') .Add('second_name', 'Smith') .EndObject .BeginObject .Add('id', '2') .Add('first_name', 'Poll') .Add('second_name', 'Scott') .EndObject .BeginObject .Add('id', '3') .Add('first_name', 'Harris') .Add('second_name', 'Hill') .EndObject .EndArray; FArray := oWriter.JSON as TJSONArray; finally oBuilder.Free; oWriter.Free; end; end; class destructor TEmpsProvider.Destroy; begin FArray.Free; end; function TEmpsProvider.GetItemByID(ARequest: TEndpointRequest): Integer; var i: Integer; begin Result := -1; for i := 0 to FArray.Count - 1 do if (FArray.Items[i] as TJSONObject).GetValue('id').Value = ARequest.Params.Values['id'] then Exit(i); end; procedure TEmpsProvider.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); begin AResponse.Body.SetValue(FArray, False); end; procedure TEmpsProvider.GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var i: Integer; begin i := GetItemByID(ARequest); if i >= 0 then AResponse.Body.SetValue(FArray.Items[i], False) else AResponse.RaiseNotFound('Item is not found'); end; procedure TEmpsProvider.Put(const AContext: TEndpointContext;

133 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 11: Mapping Endpoints to External Classes

const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var i: Integer; begin i := GetItemByID(ARequest); if i >= 0 then FArray.Remove(i); FArray.Add(ARequest.Body.GetObject.Clone as TJSONObject); end; procedure TEmpsProvider.Post(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var i: Integer; begin i := GetItemByID(ARequest); if i >= 0 then AResponse.RaiseDuplicate('Item already exists') else FArray.Add(ARequest.Body.GetObject.Clone as TJSONObject); end; procedure TEmpsProvider.Delete(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var i: Integer; begin i := GetItemByID(ARequest); if i >= 0 then FArray.Remove(i) else AResponse.RaiseNotFound('Item is not found'); end; { TTestResource } constructor TTestResource.Create(AOwner: TComponent); begin inherited Create(AOwner); Emps := TEmpsProvider.Create(Self); end; initialization Register; end.

Test the RAD Server application

Compile and Run the RAD Server application. The log will look like the following:

134 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 11: Mapping Endpoints to External Classes

Figure 172: RAD Server application log with Test resource & endpoints with "Emps." prefix.

Note that the resource is named Test and each of the endpoints are prefixed with “Emps.”. The following requests will be processed by TEmpsProvider methods of Emps object:

Figure 173: http://localhost/test/emps – calls the TEmpsProvider.Get method.

Figure 174: http://localhost/test/emps/2 – calls the TEmpsProvider.GetItem method returning the second array element.

135 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 11: Mapping Endpoints to External Classes

Figure 175: RAD Server application log shows the execution of the Emps.Get and Emps.GetItem.

See Also

Code Samples created in this chapter: • DelphiMappingEndpointsToExternalClasses

Using RAD Server Components http://docwiki.embarcadero.com/RADStudio/Rio/en/Using_RAD_Server_Components

136 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 12: Multiple Accept Types with EndpointProduce

Chapter 12: Multiple Accept Types with EndpointProduce

RAD Server’s new support for EndPoint attributes for Content-Type and Accept based mapping provide better support for resource mapping, which doesn’t depend only on the URL, but also on Accept and Content-Type HTTP request headers. This means you can have two distinct methods mapped to the same URL and HTTP verb, while returning different types of data depending on the request.

Two new EndPoint attributes have been added:

• EndpointProduce: specifies the MIME types / file extensions that can be produced by this endpoint as response to a GET method. The endpoint selection will be based on the Accept HTTP request header. • EndpointConsume: specifies the MIME types / file extensions that can be consumed by this endpoint for PUT, POST, PATCH methods. The endpoint selection will be based on Content-Type HTTP request header.

This chapter shows how RAD Server application resources can use the EndpointProduce attribute for multiple REST Get requests based on image/jpeg and application/xml MIME types.

A Simple Example

Start a RAD Server project using the project package wizard. Choose the Data Module File type and set the Resource name to AcceptTypes. De-Select all of the standard EndPoints and click the Finish button.

Delphi:

In the published section of your resource class add two method declarations decorated with ResourceSuffix and EndpointProduce attributes.

[ResourceName('AcceptTypes')] TAcceptTypesResource1 = class(TDataModule) published [ResourceSuffix ('*')] [EndpointProduce ('image/jpeg')] procedure GetImage(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); [ResourceSuffix ('*')] [EndpointProduce ('application/xml')] procedure GetText(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); end;

In the implementation section add the following code for the GetImage and GetText endpoints. procedure TAcceptTypesResource1.GetImage(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var fs: TFileStream;

137 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 12: Multiple Accept Types with EndpointProduce begin fs := TFileStream.Create('c:\temp\page\content.jpeg', fmOpenRead); AResponse.Body.SetStream(fs, 'image/jpeg', True); end; procedure TAcceptTypesResource1.GetText(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var fs: TFileStream; begin fs := TFileStream.Create('c:\temp\page\content.txt', fmOpenRead); AResponse.Body.SetStream(fs, 'text/plain', True); end;

C++:

ServerUnit.h

// EMS Resource Modules //------#ifndef ServerUnitH #define ServerUnitH //------#include #include #include #include #include //------#pragma explicit_rtti methods (public) class TAcceptTypesResource1 : public TDataModule { __published: private: public: __fastcall TAcceptTypesResource1(TComponent* Owner); void GetImage(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse); void GetText(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse); }; #endif

ServerUnit.cpp

Add the following code for the GetImage and GetText endpoints. In the Register function add the ResourceSuffix(s) and EndpointProduce attributes for the GetImage and GetText endpoints.

//------#pragma hdrstop #include "ServerUnit.h" #include //------#pragma package(smart_init) #pragma classgroup "System.Classes.TPersistent" #pragma resource "*.dfm" //------__fastcall TAcceptTypesResource1::TAcceptTypesResource1(TComponent* Owner) : TDataModule(Owner)

138 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 12: Multiple Accept Types with EndpointProduce

{ } void TAcceptTypesResource1::GetImage(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { TFileStream * fs = new TFileStream("c:\\temp\\page\\content.jpeg", fmOpenRead); AResponse->Body->SetStream(fs, "image/jpeg", True); } void TAcceptTypesResource1::GetText(TEndpointContext* Acontext, TEndpointRequest* ARequest, TEndpointResponse* AResponse) { TFileStream * fs = new TFileStream("c:\\temp\\page\\content.txt", fmOpenRead); AResponse->Body->SetStream(fs, "text/plain", True); } static void Register() { std::auto_ptr attributes(new TEMSResourceAttributes()); attributes->ResourceName = "AcceptTypes"; attributes->ResourceSuffix["GetImage"] = "*"; attributes->EndPointProduce["GetImage"] = "image/jpeg"; attributes->ResourceSuffix["GetText"] = "*"; attributes->EndPointProduce["GetText"] = "application/xml"; RegisterResource(__typeinfo(TAcceptTypesResource1), attributes.release()); } #pragma startup Register 32

Save and Build the RAD Server project.

Figure 176: Delphi project. Figure 177: C++ project.

RAD Server Executes Methods Based on Accept Headers

139 (Copyright © 2019 Embarcadero Technologies, Inc.) Chapter 12: Multiple Accept Types with EndpointProduce

How can you test the RAD Server application code? If you use a browser and use the resource name in the URL the second method will be called returning the response or you might get an error message indicating that none of the available endpoints matches the request.

Here are a few more steps to follow to test the RAD Server application’s implementation:

1) Edit the RAD Server emsserver.ini configuration file. Add a path JSON entry to the [Server.PublicPaths] section. This entry will identify the directory and HTML file to use when the http://localhost:8087/page URL is tried.

Path1={"path": "page", "directory": "C:\\temp\\page\\", "default": "index.html", "extensions": ["js", "html", "css"]}

2) Create a folder named c:\temp\page. Create text and jpeg files with the same names used in the implementation of the GetText and GetImage methods. Create an index.html file that will connect with the RAD Server application’s methods based on the different Accept Headers for each request. index.html:

a page for rad server

a page

an image below

 

some more