Глава 13. Простая публикация REST API с помощью RAD Server
Рассматривая различные доступные для Delphi варианты, наиболее богатой функциями и мощной архитектурой для создания мобильных бэкендов является RAD Server. В отличие от других типов серверных приложений Delphi, RAD Server поставляется готовым и включает основные функции «из коробки».
В этой главе мы познакомимся с ключевыми элементами RAD Server, не углубляясь слишком сильно во все функции, так как сами функции заняли бы целую книгу. Вот что мы собираемся рассмотреть:
- Настройка RAD Server
- Создание ресурсов RAD Server
- Список задач в RAD Server
- Создание клиентского приложения для RAD Server
Цель этой главы — познакомить вас с RAD Server и объяснить его основные функции, а также то, как вы можете написать свои собственные конечные точки веб-служб и вызывать их в клиентском приложении.
Технические требования
RAD Server устанавливается как часть Delphi Enterprise или Architect. RAD Server разработан как масштабируемая платформа для публикации REST API. Его функциональность расширяется путём создания пакетных библиотек Delphi BPL, которые загружаются в RAD Server при его запуске. Также требуется доступ к базе данных SQL Embarcadero InterBase, где хранится системная база данных.
Подводя итог, поддержка RAD Server доступна только в версиях Enterprise и Architect продукта, а не в редакциях Professional и Community.
Исходный код демонстраций в этой главе можно найти на GitHub: GitHub-репозиторий книги.
Настройка RAD Server
В качестве отправной точки убедитесь, что InterBase установлена и работает на вашей системе. В меню «Пуск» Windows найдите и запустите InterBase Server Manager. Окно этого служебного приложения вы можете видеть на рисунке 13.1. Если сервер не запускается, запустите его. В установке по умолчанию имя экземпляра InterBase — gds_db.
Теперь перейдите в командную строку Windows и введите команду EMSDevServer. После установки каталог bin Delphi находится в пути, поэтому RAD Server должен запуститься.
При самом первом запуске EMSDevServer или при запуске с параметром -setup вы увидите мастер установки (см. рисунок 13.2), который создаст системную базу данных RAD Server и конфигурационный ini-файл.
На первой странице мастера нам нужно ввести имя экземпляра сервера InterBase, где должна быть создана база данных RAD Server. В установке по умолчанию это gds_db. Вы можете оставить значения по умолчанию для остальных полей.
На втором экране оставьте параметры по умолчанию для создания образцов пользователей и групп.
На следующей странице мастера настройки RAD Server мы можем указать имя пользователя и пароль для доступа к консоли EMS Console. EMS Console — это отдельный исполняемый файл EMSConsole.exe, расположенный в каталоге bin Delphi.
Последняя страница мастера предоставляет сводку настройки, как вы можете видеть на рисунке 13.3. Нажмите кнопку Finish, чтобы запустить настройку RAD Server.
В установке по умолчанию у вас есть только лицензия разработки RAD Server, поэтому можно продолжить установку без лицензии при следующем запросе. Через мгновение вы должны увидеть информацию об операциях, выполненных установкой. Нажмите OK, и должна отобразиться консоль сервера разработки EMS Development Server с окном журнала, как вы можете видеть на рисунке 13.4.
В первых трёх строках журнала мы видим, что загружен конфигурационный файл emsserver.ini, расположение и имя системной базы данных RAD Server (emsserver.ib) и информация о лицензировании. Следующие строки предоставляют информацию о доступных ресурсах.
Если вы теперь нажмёте кнопку Open Browser, отобразится веб-браузер по умолчанию, указывающий на встроенный ресурс версии RAD Server, доступный по URL-адресу /version, как вы можете видеть на рисунке 13.5.
Обратите внимание, что запрос к ресурсу version был зарегистрирован в консоли. Вы также можете нажать кнопку Open Console, которая запустит исполняемый файл EMSConsole. По умолчанию EMS Server использует HTTP-порт 8080, а EMS Console — порт 8081. Нажмите кнопку Login и введите consoleuser и consolepass в качестве имени пользователя и пароля консоли.
После нажатия кнопки Login вы должны увидеть домашнюю страницу EMS Console (см. рисунок 13.6) со ссылками на различные виды доступной информации.
RAD Server настроен, и теперь мы можем начать публикацию наших собственных API, создавая новые пакеты для сервера.
Создание ресурсов RAD Server
Архитектура RAD Server элегантно спроектирована. Вы можете добавлять пользовательские ресурсы REST API через файлы библиотек пакетов Delphi, которые загружаются в RAD Server при его запуске. Расположение пакетов для загрузки хранится в ini-конфигурационном файле.
Откройте диалог New Items из меню File Delphi. Выберите категорию RAD Server и значок RAD Server Package, как вы можете видеть на рисунке 13.7.
На первой странице мастера у нас есть возможность создать пустой пакет или пакет с ресурсом. На второй странице мастера нам нужно указать имя ресурса (которое будет соответствовать URL-адресу) и базовый класс для реализации ресурса. Для этой первой демонстрации введите имя, например tododatabase, и выберите Data Module.
На третьей странице (см. рисунок 13.8) вы можете указать, какие конечные точки вы хотите добавить к ресурсу. Для первой демонстрации я выбрал только опцию конечных точек базы данных.
На четвёртой странице вас попросят выбрать подключение к базе данных. Просто выберите подключение SQLite по умолчанию и выберите одну из доступных таблиц базы данных.
Нажмите кнопку Save All, назовите модуль RSToDoDatabase_DM, а проект RSToDoDatabase.
Теперь внесите следующие изменения в компоненты модуля данных:
- Откройте редактор подключений для компонента
FDConnection1и установите значение Database в то же, которое вы использовали в предыдущих главах, скорее всегоC:\Users\Public\Documents\ToDos.db. - Переименуйте компонент
TFDQueryвqryTodo. - Измените первую строку свойства SQL на
select * from ToDos. - Переименуйте
TEMSDataSetResourceвdsrTodo.
Основным элементом конфигурации является декорирование методов или компонентов в классе модуля данных:
type
[ResourceName('tododatabase')]
TTododatabaseResource1 = class(TDataModule)
FDConnection1: TFDConnection;
qryTodo: TFDQuery;
[ResourceSuffix('Categories')]
dsrTodo: TEMSDataSetResource;
published
end;
Скомпилируйте и запустите приложение. Вы можете проверить это сопоставление URL-адресов в журнале RAD Server. В журнале вы должны увидеть раздел, подобный этому:
"RegResource": {"name":"tododatabase", "endpoints":[
{"name":"dsrTodo.List", "method":"Get",
"path":"tododatabase/Categories/",
"produce":"application/json,*;q=0.9"},
{"name":"dsrTodo.Get", "method":"Get",
"path":"tododatabase/Categories/{id}",
"produce":"application/json,*;q=0.9"}
...]
Теперь, если вы откроете браузер из пользовательского интерфейса RAD Server и замените предопределённый URL-адрес на первый путь, указанный в предыдущем журнале, tododatabase/Categories/, вы должны увидеть таблицу базы данных в формате JSON, как на рисунке 13.9.
Обратите внимание, что вы также можете извлечь одну запись, используя URL-адрес, такой как tododatabase/Categories/4, где 4 — это ID одной из записей.
Список задач в RAD Server
Теперь давайте перейдём к реализации сервера списка задач на основе архитектуры предыдущих глав:
- Создайте новую папку для проектов ресурсов RAD Server ToDo и клиента. Внутри этой папки создайте три подпапки:
resource,clientиshared. - Теперь снова запустите мастер RAD Server. На второй странице мастера на этот раз мы можем просто выбрать модуль и использовать имя ресурса
todo. - На третьей странице выберите Sample EndPoints и все пять подэлементов.
- Нажмите кнопку Finish.
Сохраните модуль ресурса как uToDoRes, а проект как ToDoPckg в подпапке resource. Скопируйте модули uToDoTypes.pas и uToDoUtils.pas в каталог shared и добавьте их в проектный пакет. Скопируйте файлы uDMToDo.pas и uDMToDo.dfm в каталог resource.
Давайте теперь начнём с фактической реализации, начиная с конечной точки Get:
procedure TToDoResource.Get(
const AContext: TEndpointContext;
const ARequest: TEndpointRequest;
const AResponse: TEndpointResponse);
begin
var AToDos := TToDos.Create;
try
GetToDoData.ToDoList(AToDos);
var RespStr := ToDosToStr(AToDos);
AResponse.Body.JSONWriter.WriteRaw(RespStr);
finally
AToDos.Free;
end;
end;
Сохраните всё и нажмите кнопку Run. Мы запускаем EMSDevServer, как показано на странице Debugger в качестве хост-приложения, и передаём наш модуль в качестве параметра ему, как вы можете видеть на рисунке 13.10.
После того как вы запустите RAD Server, откройте браузер и замените version на todo в URL-адресе. Содержимое, которое вы можете видеть на рисунке 13.11, будет почти идентично рисунку 13.9.
Теперь мы можем реализовать оставшиеся методы. Следующий — GetItem:
procedure TToDoResource.GetItem(
const AContext: TEndpointContext;
const ARequest: TEndpointRequest;
const AResponse: TEndpointResponse);
var
AToDo: TToDo;
RespStr: string;
begin
var Id := ARequest.Params.Values['item'].ToInteger;
if GetToDoData.ToDoRead(Id, AToDo) then
RespStr := ToDoToStr(AToDo)
else
RespStr := 'Failed';
AResponse.Body.JSONWriter.WriteRaw(RespStr);
end;
Следующий метод для реализации — Post:
procedure TToDoResource.Post(
const AContext: TEndpointContext;
const ARequest: TEndpointRequest;
const AResponse: TEndpointResponse);
var
AStream: TStream;
begin
if not ARequest.Body.TryGetStream(AStream) then
AResponse.RaiseBadRequest('no data');
var Bstr := AStream as TBytesStream;
var RespStr := TEncoding.UTF8.GetString(Bstr.Bytes);
var AToDo := StrToToDo(RespStr);
GetToDoData.ToDoCreate(AToDo);
end;
Следующим в списке идёт метод Put, используемый для обновления записи ToDo. Реализация почти идентична методу Post. Отличается только последняя строка кода. Вместо вызова метода ToDoCreate мы вызываем ToDoUpdate.
Последняя конечная точка для реализации отвечает за удаление элемента ToDo:
procedure TToDoResource.DeleteItem(
const AContext: TEndpointContext;
const ARequest: TEndpointRequest;
const AResponse: TEndpointResponse);
begin
var Id := ARequest.Params.Values['item'].ToInteger;
GetToDoData.ToDoDelete(Id);
end;
Создание клиентского приложения для RAD Server
Давайте теперь создадим клиентское приложение для REST API, которое мы только что построили с помощью RAD Server:
- Создайте новый пустой multi-device проект и сохраните его как
ToDoListEMSв папкеclient. - Добавьте в проект модули
uToDoTypesиuToDoUtils. - Добавьте новый модуль данных в клиентский проект. Сохраните его как
uDMToDoEMSи измените его свойствоNameнаDMToDoEMS. - Добавьте
uToDoTypesв его предложениеusesв разделеinterfaceи скопируйте пять объявлений методов интерфейсаIToDoData.
type
TDMToDoEMS = class(TDataModule, IToDoData)
private
{ Private declarations }
public
// IToDoData
function ToDoCreate(AValue: TToDo): Integer;
function ToDoRead(Id: Integer; out AValue: TToDo): Boolean;
function ToDoUpdate(AValue: TToDo): Boolean;
function ToDoDelete(Id: Integer): Boolean;
procedure ToDoList(AList: TToDos);
end;
Поместите компонент TEMSProvider на модуль данных. Он отвечает за подключение к RAD Server. Для тестирования введите 127.0.0.1 в его свойство URLHost и 8080 в свойство URLPort.
Теперь поместите пять компонентов TBackendEndpoint на модуль данных. Переименуйте их как BeToDoCreate, BeToDoRead, BeToDoUpdate, BeToDoDelete и BeToDoList. Поместите компонент TRESTResponse на модуль данных и переименуйте его как RrespToDo. С этим шагом мы создали модуль данных, как на рисунке 13.12.
Реализация метода ToDoList проста:
procedure TDMToDoEMS.ToDoList(AList: TToDos);
begin
AList.Clear;
BeToDoList.Execute;
StrToToDos(RrespToDo.Content, AList);
end;
Метод ToDoRead:
function TDMToDoEMS.ToDoRead(
Id: Integer; out AValue: TToDo): Boolean;
begin
BeToDoRead.ResourceSuffix := Id.ToString;
BeToDoRead.Execute;
Result := RrespToDo.Content <> 'Failed';
if Result then
AValue := StrToToDo(RrespToDo.Content);
end;
Метод ToDoCreate (после добавления модуля REST.Types в предложение uses):
function TDMToDoEMS.ToDoCreate(AValue: TToDo): Integer;
begin
Result := 0;
var StrStr := TStringStream.Create(
ToDoToStr(AValue), TEncoding.UTF8);
try
BeToDoCreate.Params.Clear;
BeToDoCreate.AddBody(StrStr,
TRESTContentType.ctAPPLICATION_JSON);
BeToDoCreate.Execute;
finally
StrStr.Free;
end;
end;
Следующий метод для реализации — ToDoUpdate. Он будет иметь очень похожую реализацию на метод ToDoCreate. Просто убедитесь, что изменили свойство Method компонента BeToDoUpdate на rmPUT.
Последний метод для реализации — ToDoDelete. Измените свойство Method компонента BeToDoDelete на rmDELETE:
function TDMToDoEMS.ToDoDelete(Id: Integer): Boolean;
begin
BeToDoDelete.ResourceSuffix := Id.ToString;
BeToDoDelete.Execute;
Result := True;
end;
Вот и всё. Сохраните всё и запустите клиентское приложение. Вы должны просто запустить и отобразить данные ToDo из основной базы данных SQLite, полученные от ресурса REST API, размещённого в бэкенде RAD Server, как вы можете видеть на рисунке 13.13.
Как вы можете видеть, RAD Server — очень мощный продукт. Это идеальный бэкенд для мобильных приложений, написанных на Delphi.
Резюме
В этой главе мы увидели, как использовать RAD Server для построения многоуровневых архитектур и предоставления множества повторно используемых функций для создания отличных мобильных бэкендов для ваших кроссплатформенных мобильных приложений Delphi.
Следующая глава изменит фокус; мы вернёмся к мобильной разработке и сосредоточимся на заключительных этапах мобильной разработки: развёртывании в магазинах приложений.