Глава 13. Простая публикация REST API с помощью RAD Server

Рассматривая различные доступные для Delphi варианты, наиболее богатой функциями и мощной архитектурой для создания мобильных бэкендов является RAD Server. В отличие от других типов серверных приложений Delphi, 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.

Рисунок 13.1: Менеджер сервера InterBase
Рисунок 13.1: Менеджер сервера InterBase

Теперь перейдите в командную строку Windows и введите команду EMSDevServer. После установки каталог bin Delphi находится в пути, поэтому RAD Server должен запуститься.

Примечание: Обратите внимание, что во многих местах вы увидите слово EMS при обращении к RAD Server. Оно расшифровывается как Enterprise Mobility Services и является прежним названием RAD Server.

При самом первом запуске EMSDevServer или при запуске с параметром -setup вы увидите мастер установки (см. рисунок 13.2), который создаст системную базу данных RAD Server и конфигурационный ini-файл.

Рисунок 13.2: Вкладка «Новая база данных» в мастере настройки RAD Server
Рисунок 13.2: Вкладка «Новая база данных» в мастере настройки RAD Server

На первой странице мастера нам нужно ввести имя экземпляра сервера InterBase, где должна быть создана база данных RAD Server. В установке по умолчанию это gds_db. Вы можете оставить значения по умолчанию для остальных полей.

На втором экране оставьте параметры по умолчанию для создания образцов пользователей и групп.

На следующей странице мастера настройки RAD Server мы можем указать имя пользователя и пароль для доступа к консоли EMS Console. EMS Console — это отдельный исполняемый файл EMSConsole.exe, расположенный в каталоге bin Delphi.

Последняя страница мастера предоставляет сводку настройки, как вы можете видеть на рисунке 13.3. Нажмите кнопку Finish, чтобы запустить настройку RAD Server.

Рисунок 13.3: Вкладка «Завершение» мастера настройки RAD Server
Рисунок 13.3: Вкладка «Завершение» мастера настройки RAD Server

В установке по умолчанию у вас есть только лицензия разработки RAD Server, поэтому можно продолжить установку без лицензии при следующем запросе. Через мгновение вы должны увидеть информацию об операциях, выполненных установкой. Нажмите OK, и должна отобразиться консоль сервера разработки EMS Development Server с окном журнала, как вы можете видеть на рисунке 13.4.

Рисунок 13.4: Главное окно RAD Server
Рисунок 13.4: Главное окно RAD Server

В первых трёх строках журнала мы видим, что загружен конфигурационный файл emsserver.ini, расположение и имя системной базы данных RAD Server (emsserver.ib) и информация о лицензировании. Следующие строки предоставляют информацию о доступных ресурсах.

Если вы теперь нажмёте кнопку Open Browser, отобразится веб-браузер по умолчанию, указывающий на встроенный ресурс версии RAD Server, доступный по URL-адресу /version, как вы можете видеть на рисунке 13.5.

Рисунок 13.5: Встроенный ресурс версии RAD Server в веб-браузере
Рисунок 13.5: Встроенный ресурс версии RAD Server в веб-браузере

Обратите внимание, что запрос к ресурсу version был зарегистрирован в консоли. Вы также можете нажать кнопку Open Console, которая запустит исполняемый файл EMSConsole. По умолчанию EMS Server использует HTTP-порт 8080, а EMS Console — порт 8081. Нажмите кнопку Login и введите consoleuser и consolepass в качестве имени пользователя и пароля консоли.

После нажатия кнопки Login вы должны увидеть домашнюю страницу EMS Console (см. рисунок 13.6) со ссылками на различные виды доступной информации.

Рисунок 13.6: Домашняя страница EMS Console
Рисунок 13.6: Домашняя страница EMS Console

RAD Server настроен, и теперь мы можем начать публикацию наших собственных API, создавая новые пакеты для сервера.

Создание ресурсов RAD Server

Архитектура RAD Server элегантно спроектирована. Вы можете добавлять пользовательские ресурсы REST API через файлы библиотек пакетов Delphi, которые загружаются в RAD Server при его запуске. Расположение пакетов для загрузки хранится в ini-конфигурационном файле.

Откройте диалог New Items из меню File Delphi. Выберите категорию RAD Server и значок RAD Server Package, как вы можете видеть на рисунке 13.7.

Рисунок 13.7: Мастер RAD Server Package в диалоге New Items
Рисунок 13.7: Мастер RAD Server Package в диалоге New Items

На первой странице мастера у нас есть возможность создать пустой пакет или пакет с ресурсом. На второй странице мастера нам нужно указать имя ресурса (которое будет соответствовать URL-адресу) и базовый класс для реализации ресурса. Для этой первой демонстрации введите имя, например tododatabase, и выберите Data Module.

На третьей странице (см. рисунок 13.8) вы можете указать, какие конечные точки вы хотите добавить к ресурсу. Для первой демонстрации я выбрал только опцию конечных точек базы данных.

Рисунок 13.8: Страница определения конечных точек мастера RAD Server Package
Рисунок 13.8: Страница определения конечных точек мастера RAD Server Package

На четвёртой странице вас попросят выбрать подключение к базе данных. Просто выберите подключение SQLite по умолчанию и выберите одну из доступных таблиц базы данных.

Нажмите кнопку Save All, назовите модуль RSToDoDatabase_DM, а проект RSToDoDatabase.

Теперь внесите следующие изменения в компоненты модуля данных:

Основным элементом конфигурации является декорирование методов или компонентов в классе модуля данных:

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.

Рисунок 13.9: Вся таблица, перечисленная модулем RAD Server RSToDoDatabase
Рисунок 13.9: Вся таблица, перечисленная модулем RAD Server RSToDoDatabase

Обратите внимание, что вы также можете извлечь одну запись, используя URL-адрес, такой как tododatabase/Categories/4, где 4 — это ID одной из записей.

Список задач в RAD Server

Теперь давайте перейдём к реализации сервера списка задач на основе архитектуры предыдущих глав:

  1. Создайте новую папку для проектов ресурсов RAD Server ToDo и клиента. Внутри этой папки создайте три подпапки: resource, client и shared.
  2. Теперь снова запустите мастер RAD Server. На второй странице мастера на этот раз мы можем просто выбрать модуль и использовать имя ресурса todo.
  3. На третьей странице выберите Sample EndPoints и все пять подэлементов.
  4. Нажмите кнопку 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.

Рисунок 13.10: Вкладка Debugger в Project Options в модуле RAD Server
Рисунок 13.10: Вкладка Debugger в Project Options в модуле RAD Server

После того как вы запустите RAD Server, откройте браузер и замените version на todo в URL-адресе. Содержимое, которое вы можете видеть на рисунке 13.11, будет почти идентично рисунку 13.9.

Рисунок 13.11: Записи ToDo, перечисленные как JSON в веб-браузере
Рисунок 13.11: Записи ToDo, перечисленные как JSON в веб-браузере

Теперь мы можем реализовать оставшиеся методы. Следующий — 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:

  1. Создайте новый пустой multi-device проект и сохраните его как ToDoListEMS в папке client.
  2. Добавьте в проект модули uToDoTypes и uToDoUtils.
  3. Добавьте новый модуль данных в клиентский проект. Сохраните его как uDMToDoEMS и измените его свойство Name на DMToDoEMS.
  4. Добавьте 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.

Рисунок 13.12: Компоненты provider, endpoint и response на модуле данных
Рисунок 13.12: Компоненты provider, endpoint и response на модуле данных

Реализация метода 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.

Рисунок 13.13: Клиентское приложение, использующее RAD Server
Рисунок 13.13: Клиентское приложение, использующее RAD Server

Как вы можете видеть, RAD Server — очень мощный продукт. Это идеальный бэкенд для мобильных приложений, написанных на Delphi.

Резюме

В этой главе мы увидели, как использовать RAD Server для построения многоуровневых архитектур и предоставления множества повторно используемых функций для создания отличных мобильных бэкендов для ваших кроссплатформенных мобильных приложений Delphi.

Следующая глава изменит фокус; мы вернёмся к мобильной разработке и сосредоточимся на заключительных этапах мобильной разработки: развёртывании в магазинах приложений.