Jump to content

ServerModule как сделать REST API


dbf_usr

Recommended Posts

Делаю REST API, в ServerModule есть две проблемы:

1. Отлавливаю обращение и принимаю JSON запрос и даже отправляю JSON клиенту.

Но мене нужно отправить данные, а они в DataModule, а он на этом этапе еще не существует.

По хорошему нужно запустить новый сеанс и в нем уже запускать процедуры в которых добывать данные, потом их как-то передать в ServerModule для отправки

2. И еще проблема - HyperServer режет заголовки, вместо JSON приходит только "<HTML><BODY><B>200 OK</B></BODY></HTML>"

Если приложение запущено без HyperServer, то все работает.

Не знаю как это сделать. Помогите пожалуйста!

Всем за ранее благодарен.

ниже моя процедура

procedure TUniServerModule.UniGUIServerModuleHTTPCommand(
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
  var Handled: Boolean);
   var
  RequestData: TStringStream;
  JSONRequest: TJSONObject;
  sam, key,option: string;
  today : TDateTime;
begin
  if ARequestInfo.Document = '/api/data' then
  begin
    RequestData := TStringStream.Create;
    try
      RequestData.LoadFromStream(ARequestInfo.PostStream);
      JSONRequest := TJSONObject.ParseJSONValue(RequestData.DataString) as TJSONObject;
      try
        if JSONRequest.TryGetValue<string>('sam', sam) and  JSONRequest.TryGetValue<string>('key', key) then
        begin
          AResponseInfo.ContentType := 'application/json';
          if JSONRequest.TryGetValue<string>('option', option) then
          begin
            if option = 'getuser' then
                  AResponseInfo.ContentText := UniMainModule.API_GetUser(key); // ТУТ ПОПЫТКА ВЫЗОВА ФУНКЦИИ ИЗ ДАТАМОДУЛЯ

            if option = 'gettemplates' then
                  AResponseInfo.ContentText := UniMainModule.API_GetTrmplates(key); // ТУТ ПОПЫТКА ВЫЗОВА ФУНКЦИИ ИЗ ДАТАМОДУЛЯ
            end
          else
          AResponseInfo.ContentText :=  '{ "option": "error-0" }';  
          AResponseInfo.ContentEncoding := 'utf-8';
          AResponseInfo.ContentLanguage := 'ru';
          AResponseInfo.CharSet := 'utf-8';
          AResponseInfo.ResponseNo := 200;
          today:=now;
        end
        else
        begin
          AResponseInfo.ResponseNo := 400; 
        end;
      finally
        JSONRequest.Free;
      end;
    finally
      RequestData.Free;
    end;
  end
  else
  begin
    AResponseInfo.ResponseNo := 404;
  end;
end;

 

Link to comment
Share on other sites

19 hours ago, dbf_usr said:

Но мене нужно отправить данные, а они в DataModule, а он на этом этапе еще не существует.

Добрый день, 

А что за данные в DataModule, запросы к БД?

Link to comment
Share on other sites

8 minutes ago, dbf_usr said:

Да, там запросы к БД и логика.

В таком случае, Вам нужно подключаться, и создавать запросы к БД динамически в UniServerModule... 

Link to comment
Share on other sites

1 hour ago, Sherzod said:

В таком случае, Вам нужно подключаться, и создавать запросы к БД динамически в UniServerModule... 

Спасибо большое!!!

Link to comment
Share on other sites

Есть еще вопрос. 

Если я использую HyperServer то пиложение не запускается пустая страница, нет формы с логином и фонового изображения.  А таже при обращении к API ответ приходит об ошибке. Не работает.

Если приложение запущено без HyperServer, то все работает, и приложение и API. Это ошибка или нужно что-то настроить в  HyperServer?

Заранее благодарен!

Link to comment
Share on other sites

18 minutes ago, Sherzod said:

Скорее всего у Вас установлена антивирусная программа, которая блокирует трафик. Нужно удалить...

Никаких антивирусов нет. Если я не использую UniGUIServerModuleHTTPCommand, то приложение через HyperServer работает нормально.

 
Link to comment
Share on other sites

6 hours ago, dbf_usr said:

использую UniGUIServerModuleHTTPCommand

Кажется Вы не используете эту переменную должным образом:

On 6/19/2023 at 9:11 PM, dbf_usr said:
var Handled: Boolean);

 

Link to comment
Share on other sites

13 hours ago, Sherzod said:

Кажется Вы не используете эту переменную должным образом:

 

При запуске приложения через HyperServer, приложение возращает вот это   <HTML><BODY><B>200 OK</B></BODY></HTML>

вместо JSON ответа. Если запускать приложение без HyperServer то JSON приходит корректный.

Вот исправленная процедура, а ниже скрины ответа приложения. Там видно что в заголовке тип ответа меняется Content-Type: application/json; charset=utf-8    на  text/html; charset=utf-8. Поэтому и появляется проблема. Видимо HyperServer переделывает заголовки и обрезает ответ. Как можно это исправить, может я опять где-то настройки не сделал? За ранее очень благодарен за ответ.

procedure TUniServerModule.UniGUIServerModuleHTTPCommand(
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
  var Handled: Boolean);
 var
  RequestData: TStringStream;
  JSONRequest: TJSONObject;
  sam, key,option: string;
  today : TDateTime;
begin
  if ARequestInfo.Document = '/api/data' then
  begin
    RequestData := TStringStream.Create;
    try
      RequestData.LoadFromStream(ARequestInfo.PostStream);
      JSONRequest := TJSONObject.ParseJSONValue(RequestData.DataString) as TJSONObject;
      try
        if JSONRequest.TryGetValue<string>('sam', sam) and  JSONRequest.TryGetValue<string>('key', key) then
        begin
        AResponseInfo.ContentEncoding := 'utf-8';
          AResponseInfo.ContentLanguage := 'ru';
          AResponseInfo.CharSet := 'utf-8';
          AResponseInfo.ResponseNo := 200;
          AResponseInfo.ContentType := 'application/json';
          if JSONRequest.TryGetValue<string>('option', option) then
          begin
            if option = 'getuser' then
                  AResponseInfo.ContentText := UniServerModule.API_GetUser(key); // функция возвращает JSON
                  Handled := True;

            if option = 'gettemplates' then
                  AResponseInfo.ContentText := UniServerModule.API_GetTrmplates(key); // функция возвращает JSON
            end
          else
             AResponseInfo.ContentText :=  '{ "option": "error-0" }';
            Handled := True;
        end
        else
        begin
          AResponseInfo.ResponseNo := 400;  
          Handled := True;
        end;
      finally
        JSONRequest.Free;
      end;
    finally
      Handled := false;
      RequestData.Free;
    end;
  end
  else
  begin
    Handled := false;
  end;

end;

 

Снимок экрана 2023-06-21 в 18.35.49.png

Снимок экрана 2023-06-21 в 18.39.12.png

Link to comment
Share on other sites

On 6/21/2023 at 5:14 AM, Sherzod said:

Кажется Вы не используете эту переменную должным образом:

 

Выше описал проблему. Эта ошибка в HyperServer или ограничение? То есть нельзя использовать HyperServer с подобными приложениями? Я правильно понял? 

Link to comment
Share on other sites

4 hours ago, dbf_usr said:

Эта ошибка в HyperServer или ограничение? То есть нельзя использовать HyperServer с подобными приложениями? Я правильно понял? 

Нет. Тут не должно быть ограничений. Я разрабатывал подобный сервис.

Создайте простой тестовый случай если есть возможность, мы проверим.

Link to comment
Share on other sites

40 minutes ago, Sherzod said:

Нет. Тут не должно быть ограничений. Я разрабатывал подобный сервис.

Создайте простой тестовый случай если есть возможность, мы проверим.

Сделал простой тестовый пример. Очень жду результатов! Заранее благодарен !!!!!

Error_api.zip

Link to comment
Share on other sites

11 hours ago, dbf_usr said:

Сделал простой тестовый пример. Очень жду результатов! Заранее благодарен !!!!!

Какую версию uniGUI, Delphi используете? Я даже не смог запустить...

Link to comment
Share on other sites

  • 1 month later...

Используется последняя версия компонент на текущий момент.

Удалось запустить проект, но  только при помощи  ISAPI и под IIS.

Вывод:

UNIGUI - не имеет достаточной защищенности по HTTPS, при использовании его в виде ServerStandAlone, поскольку он использует устаревший OpenSSL, который не поддерживает последние версии шифрования и сертификатов. Вы не сможете разрабатывать сервисов работающих в iOS, MacOS - они просто не принимают соединение с старым шифрованием, а ноновое UniGUI не способен. Для продакшина возможно использовать только ISAPI под IIS. Что значительно ухудшает его масштабируемость, Гипер сервер становится просто бесполезен.  Готовьтесь постоянно "передергивать"  IIS, потому что в инструкции по настройке ISAPI под IIS отключена функция перезапуска приложения сервером и оно будет у вас виснут. Если раньше это решалось при помощи Гипресервера, то теперь будете руками перезапускать  IIS, когда к вам начнут звонить ваши клиенты и жаловаться, что сервис не работает. Интересно через сколько обращений они откажутся от вашего сервиса? 

Link to comment
Share on other sites

нормально работает связка nginx (TLS 1.3, Let's Encrypt + CertBot) proxy_pass -> HyperServer (без SSL, http://*.*.*.*:port/)

Linux (Nginx) + Windows (HyperServer, App) + Linux (PostgreSQL)

600-800 активных тяжелых сессий на протяжении рабочего дня

Link to comment
Share on other sites

  • 2 months later...
On 8/21/2023 at 4:22 PM, Kos said:

нормально работает связка nginx (TLS 1.3, Let's Encrypt + CertBot) proxy_pass -> HyperServer (без SSL, http://*.*.*.*:port/)

Linux (Nginx) + Windows (HyperServer, App) + Linux (PostgreSQL)

600-800 активных тяжелых сессий на протяжении рабочего дня

Вы не сможене взаимодействовать с приложениями iOS и  MAC OS.   Они просто не захотят устанавливать соединения. Удалось подружить только через IIS, сертификаты прописаваются в IIS. HyperServer пока к сожалению на это не способен. Пришлось выносить в отдельное приложение и запускать его под IIS.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...