From Clomosy Docs

In Clomosy, the TclRest component is a component that facilitates interaction with RESTful services for data transfer. REST (Representational State Transfer) is a popular architecture for data transfer between web-based services.

With the TclRest component in Clomosy, you can easily communicate with such services and exchange data.

Using the TclRest component, you can make requests to a RESTful service (GET, POST, etc.), receive responses, and process these responses.

Feature Use of Definition
TclRest clRest : TclRest; An object of the TclRest class is defined.
Create clRest = TclRest.Create; A new TclRest object is created on the form.
BaseURL clRest.BaseURL = 'https://dummyjson.com/auth/login'; The URL address to access is given.
Resource clRest.Resource = 'users/123'; Defines the API path to be used after the base URL.
AddHeader clRest.AddHeader('Custom-Header', 'Value'); //Optional additional title
clRest.AddHeader('Authorization','Bearer your_api_key');
The specified header is added to the HTTP request. It takes two parameters: the first parameter is the header name, and the second parameter provides information about the media type of the data sent to the server.

In the example, the "Authorization" header is used to carry authentication information. The value of the 'Authorization' header usually contains a Bearer token. For example, a value like Bearer your_api_key is used. You should replace your_api_key with a valid API key or token.
Another example allows you to add your custom headers as well. In the example, we added a Custom-Header header and its corresponding value. This entirely depends on the requirements of the API.

ContentType clRest.ContentType = 'application/json';
ShowMessage(clRest.ContentType)
Specifies the content type of the data to be sent (e.g., application/json, application/x-www-form-urlencoded).
RemoveHeader clRest.RemoveHeader('Authorization'); Removes a previously added header.
Accept clRest.Accept = 'application/json'; // 'text/xml' etc. Specifies the media type the server will accept in the response. It is indicated that data will be received in JSON format in the example.

The Accept property also defaults to sending values in JSON format.

Method clRest.Method = rmPOST; //rmGET,rmPUT,rmDELETE

Specifies the type of HTTP request to be made. If you want to add new data to a resource or update an existing one with a POST request, you use rmPOST. If you want to retrieve the data of a resource with a GET request, you use rmGET.

Body clRest.Body = '{"name": "Jack", "age": 35}'; Contains the body data for the request (commonly used in POST and PUT requests).
ClearBody clRest.ClearBody; Clears the previously added request body.
FormDataBody clRest.FormDataBody = 'password=123456';
ShowMessage(clRest.FormDataBody);
ShowMessage(clRest.FormDataBody.Text);
Used in requests containing form data (multipart/form-data).
AddBody clRest.AddBody('{"username":"kminchelle","password":"0lelplR"}','application/json'); Adds the provided data to the body of the specified request. This body forms the part where the data is sent in requests like POST. The data specified in the request is transmitted to the server through this body. It takes two parameters. The first parameter specifies the data to be sent in the POST request body, and the second parameter indicates the media type of the sent data.
AddQuery clRest.AddQuery('id', '123'); Adds a parameter to the query string of a URL. For example, it is used to create a URL like https://api.example.com/users?id=123.
GetQuery QueryValue = clRest.GetQuery('id'); //QueryValue : String; Returns the query string parameter with the specified AKey value.
RemoveQuery clRest.RemoveQuery('id'); Removes a previously added query parameter.
AddUrlSegment clRest.Resource = 'users/{userId}';
clRest.AddUrlSegment('userId', '123');
It is used to dynamically insert variables into a URL. For example, it fills the {userId} variable in a URL template like https://api.example.com/users/{userId}.
RemoveUrlSegment clRest.RemoveUrlSegment('userId'); Removes a previously added URL segment variable.
Execute clRest.Execute; When this method is executed, the TclRest component performs the specified request and receives the response from the server. Executes the REST request synchronously. This means the code does not proceed until this function completes.
OnCompleted clRest.OnCompleted = CompletedProc; //CompletedProc : void Triggered when the ExecuteAsync operation is completed.
CompletedTrigger clRest.CompletedTrigger; Triggers the OnCompleted event when ExecuteAsync is completed.
ExecuteAsync clRest.OnCompleted = CompletedProc; //CompletedProc : void
clRest.ExecuteAsync;
Executes the REST request asynchronously (in the background). The code continues running, and an event is triggered when the operation is complete (therefore, the OnCompleted property should be defined beforehand).
Response ShowMessage(clRest.Response); You can access the details and content of the response from the server.
ClearParams clRest.ClearParams; Clears all previously added parameters (header, query, segment).
StatusCode ShowMessage(clRest.StatusCode); Returns the HTTP status code (200, 404, 500, etc.).
StatusText ShowMessage(clRest.StatusText); Returns the description of the HTTP status code (e.g., OK, Not Found, etc.).
ConnectTimeout clRest.ConnectTimeOut = 60000; Sets the connection timeout duration in milliseconds.
ResponseHeaders ShowMessage(clRest.ResponseHeaders.Text);
ShowMessage(clRest.ResponseHeaders.Count);
ShowMessage(clRest.ResponseHeaders[0]);
Contains the response headers returned from the server.
The Text property returns the response headers from the server.

The total number of received HTTP headers is shown by Count.
A specific HTTP header can be retrieved by specifying its index.

GetHeader HeaderValue = clRest.GetHeader('Content-Type'); //HeaderValue : String; Returns the HTTP header with the specified AKey value.
ProxyServer clRest.ProxyServer = '192.168.1.100'; Specifies the address of the proxy server to be used.
ProxyUsername clRest.ProxyUsername = 'myProxyUser'; Sets the username to be used when connecting to the proxy server.
ProxyPassword clRest.ProxyPassword = 'myProxyPass'; Sets the password required to connect to the proxy server if a proxy is being used.
ProxyPort clRest.ProxyPort = 8080; Sets the port number of the proxy server.

Example 1 - GET/POST

var
  Form1 : TclForm; 
  clRest : TCLRest;
  Button1 : TCLButton;

void GetPostMethod;
{
  clRest.Execute;
  ShowMessage(clRest.Response);
}

{
  Form1 = TclForm.Create(Self);
  
  Button1 = Form1.AddNewButton(Form1,'Button1', 'Click');
  Form1.AddNewEvent(Button1, tbeOnClick, 'GetPostMethod');
  
  clRest=TCLRest.Create;
  
  // Post
  
  clRest.BaseURL = 'https://jsonplaceholder.typicode.com/posts';
  clRest.Accept = 'application/json';
  clRest.Method = rmPOST;
  clRest.AddBody('{"name":"John","job":"Developer"}','application/json');
  //clRest.AddHeader('Content-Type','application/json');
  
  // Get
  /*
  clRest.BaseURL = 'https://jsonplaceholder.typicode.com/posts/1';
  clRest.Accept = 'application/json';
  clRest.Method = rmGET;
  clRest.AddHeader('Custom-Header', 'Value'); //Optional additional title
  //clRest.AddHeader('Authorization', 'Bearer your_api_key');
  
  */
  Form1.Run;
}

Example 2 - GET/POST/PUT/DELETE

This code creates a form and adds buttons to perform "GET, POST, PUT, and DELETE" operations, setting up a REST client. The "TclRest" object sends requests to a REST API, and the response is displayed in the "Memo1" component. The "SendRequest" procedure initiates an "asynchronous request" based on the specified HTTP method ("rmGET, rmPOST, rmPUT, rmDELETE"), URL, and optionally a JSON body. When a response is received, "CompletedProc" executes to update the Memo. Clicking the buttons triggers the corresponding request function, which directs the call to "SendRequest" and performs the API request.

var
  MyForm:TCLForm;
  btnGet, btnPost, btnDelete,btnPut : TclButton;
  RestClient: TclRest;
  Memo1 : TclMemo;

void CompletedProc;
{
  Memo1.Lines.Clear;
  Memo1.Lines.Add(RestClient.Response);
  
  RestClient.Free;
  RestClient = Nil;
}
  
void SendRequest(AMethod,AURL,ABody);
{
  RestClient = TclRest.Create;
  try
    try
      RestClient.Accept = 'application/json';
      RestClient.ContentType = 'application/json';
      RestClient.ConnectTimeOut = 60000;
      RestClient.BaseURL = AURL;
      if (ABody <> '')
        RestClient.Body = ABody;
      RestClient.Method = AMethod;
      RestClient.OnCompleted = 'CompletedProc';
      RestClient.ExecuteAsync;
    except
    ShowMessage('Exception Class: '+LastExceptionClassName+' Exception Message: '+LastExceptionMessage);
    }
  finally
  }
}

//  GET Request
void GetRequest;
{
  SendRequest(rmGet,'https://jsonplaceholder.typicode.com/posts/8','');
}

//  POST Request
void PostRequest;
{
  SendRequest(rmPost,'https://jsonplaceholder.typicode.com/posts','{"title": "Hello", "body": "This is a test", "userId": 1}');
}

//  DELETE Request
void DeleteRequest;
{
  SendRequest(rmDELETE,'https://jsonplaceholder.typicode.com/posts/5','');
}

// Put Request
void PutRequest;
{
  SendRequest(rmPUT,'https://jsonplaceholder.typicode.com/posts/1','{"id": 1, "title": "Updated", "body": "New data", "userId": 1}');
}

{
  MyForm = TCLForm.Create(Self);
  
  btnGet = MyForm.AddNewButton(MyForm,'btnGet','Get');
  btnGet.ALign = alMostTop;
  btnGet.Height = 50;
  MyForm.AddNewEvent(btnGet,tbeOnClick,'GetRequest');
  
  btnPost = MyForm.AddNewButton(MyForm,'btnPost','Post');
  btnPost.ALign = alMostTop;
  btnPost.Height = 50;
  MyForm.AddNewEvent(btnPost,tbeOnClick,'PostRequest');
  
  btnDelete = MyForm.AddNewButton(MyForm,'btnDelete','Delete');
  btnDelete.ALign = alMostTop;
  btnDelete.Height = 50;
  MyForm.AddNewEvent(btnDelete,tbeOnClick,'DeleteRequest');
  
  btnPut = MyForm.AddNewButton(MyForm,'btnPut','Put');
  btnPut.Align = alMostTop;
  btnPut.Height = 50;
  MyForm.AddNewEvent(btnPut,tbeOnClick,'PutRequest');
  
  Memo1 = MyForm.AddNewMemo(MyForm,'Memo1','--');
  Memo1.ALign = alTop;
  Memo1.Margins.Top = 10;
  Memo1.Height = (MyForm.clWidth / 3);
  
  MyForm.Run;
}

Example 3 - OPENAI API CHATBOT

This code creates a chatbot using OpenAI's API. The user types their question into a text box (QuestionEdit) and presses the "Send" button to make a request to the OpenAI API. Once the API response is received, it is added to the message list (MsgList) and displayed on the screen. The requests are sent to OpenAI's chat/completions endpoint using the POST method through the TclRest object. User authorization is checked, and only certain profiles are allowed to send messages.


var
  MainForm : TclForm;
  QuestionEdit : TclProEdit;
  SendButton : TClProButton;
  ChatPnl,MsjPnl:TclProPanel;
  MsgList:TclMemo;
  MainLyt : TClLayout;
  MainTitleLbl:TclLabel;
  strIncomingData : String;
  Rest: TclRest;
  API_KEY: string;
  RequestBody: string;

void ACompletedProc;
{
  //strIncomingData = Rest.Response;
  strIncomingData = Clomosy.CLParseJSON(Rest.Response,'choices.0.message.content');
  MsgList.Lines.Add(strIncomingData);
}

void RestCreate(ABaseUrl, token,ABody :String);
{
  Rest = TclRest.Create;
  Rest.Accept = 'application/json';
  Rest.ContentType = 'application/json';
  Rest.Method = rmPOST;
  Rest.ConnectTimeOut = 30000;
  Rest.BaseURL = ABaseUrl;
  Rest.AddHeader('Authorization',token);
  Rest.Body = ABody;
  Rest.OnCompleted = 'ACompletedProc';
  Rest.ExecuteAsync;
  
}

void BtnSendClick;
{
 if ((Clomosy.AppUserProfile==1) && (QuestionEdit.Text <> '')) 
 {
  if QuestionEdit.Text <> ''
  {
    MsgList.Lines.Add(QuestionEdit.Text);
    MsgList.ScrollTo(0,MsgList.Lines.Count*MsgList.Lines.Count,True);
  
    API_KEY = 'token';  // Enter your own API key here.
    
    RequestBody = '{' +
  '  "model": "gpt-4-turbo",' +  // Change model if needed
  '  "messages": [' +
  '    {' +
  '      "role": "system",' +
  '      "content": "You are a helpful assistant."' +
  '    },' +
  '    {' +
  '      "role": "user",' +
  '      "content": "' + QuestionEdit.Text+ '"' +
  '    }' +
  '  ],' +
  '  "temperature": 0.7' +  // Adjust creativity level
  '}';

    RestCreate('https://api.openai.com/v1/chat/completions' ,API_KEY,RequestBody);
    QuestionEdit.Text = '';
  } else
  {
    ShowMessage('Please, ask a question!');
  }
 }
}


void SetMiddlePanel;
{
  MsjPnl=MainForm.AddNewProPanel(MainLyt,'MsjPnl');
  MsjPnl.Align = AlBottom;
  MsjPnl.Height = 100;
  MsjPnl.Margins.Top = 5;
  MsjPnl.Margins.Bottom = 20;
  MsjPnl.Margins.Left = 10;
  MsjPnl.Margins.Right = 10;
  MsjPnl.SetclProSettings(ChatPnl.clProSettings);
  
  QuestionEdit = MainForm.AddNewProEdit(MsjPnl,'QuestionEdit','Ask a question...');
  QuestionEdit.Align = AlClient;
  QuestionEdit.Margins.Left = 10;
  QuestionEdit.Margins.Right = 10;
  QuestionEdit.Margins.Top = 10;
  QuestionEdit.Margins.Bottom = 10;
  QuestionEdit.clProSettings.BorderColor = clAlphaColor.clHexToColor('#3bf5c0');
  QuestionEdit.clProSettings.FontHorzAlign = palLeading;
  QuestionEdit.clProSettings.BorderWidth = 1;
  QuestionEdit.clProSettings.IsRound = True;
  QuestionEdit.clProSettings.RoundHeight = 10;
  QuestionEdit.clProSettings.RoundWidth = 10;
  QuestionEdit.clProSettings.WordWrap = True;
  QuestionEdit.SetclProSettings(QuestionEdit.clProSettings);
  
  SendButton = MainForm.AddNewProButton(MsjPnl,'SendButton','Send');
  SendButton.Align = AlRight;
  SendButton.Width = MsjPnl.Width/4;
  SendButton.Margins.Bottom = 10;
  SendButton.Margins.Top = 10;
  SendButton.Margins.Right = 10;
  SendButton.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#1814F3');
  SendButton.clProSettings.FontColor = clAlphaColor.clHexToColor('#ffffff');
  SendButton.clProSettings.FontSize = 16;
  SendButton.clProSettings.TextSettings.Font.Style = [fsBold];
  SendButton.clProSettings.IsRound = True;
  SendButton.clProSettings.RoundHeight = 10;
  SendButton.clProSettings.RoundWidth = 10;
  SendButton.SetclProSettings(SendButton.clProSettings);
  
  MainForm.AddNewEvent(SendButton,tbeOnClick,'BtnSendClick');
}

void SetBigPanel;
{
  ChatPnl=MainForm.AddNewProPanel(MainLyt,'ChatPnl');
  ChatPnl.Align = AlClient;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Left = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.Margins.Right = 10;
  ChatPnl.clProSettings.BorderColor = clAlphaColor.clHexToColor('#008000');
  ChatPnl.clProSettings.BorderWidth = 0;
  ChatPnl.clProSettings.IsRound = True;
  ChatPnl.clProSettings.RoundHeight = 5;
  ChatPnl.clProSettings.RoundWidth = 5;
  ChatPnl.clProSettings.BackgroundColor = clAlphaColor.clHexToColor('#f7f7f7');
  ChatPnl.SetclProSettings(ChatPnl.clProSettings);
  
  MsgList= MainForm.AddNewMemo(ChatPnl,'MsgList','');
  MsgList.Align = alClient;
  MsgList.ReadOnly = True;
  MsgList.Margins.Top= 20;
  MsgList.Margins.Left= 20;
  MsgList.Margins.Bottom= 20;
  MsgList.Margins.Right =20;
  MsgList.TextSettings.Font.Size=26;
  MsgList.TextSettings.WordWrap = True;
  MsgList.EnabledScroll = True;
}

void SetMainTitle;
{
  MainTitleLbl= MainForm.AddNewLabel(MainForm.LytTopBar,'MainTitleLbl',' Clomosy Artificial Intelligence');
  MainTitleLbl.StyledSettings = ssFamily;
  MainTitleLbl.TextSettings.Font.Size=20;
  MainTitleLbl.Align = alLeft;
  MainTitleLbl.Margins.Left= 14;
  MainTitleLbl.Margins.Top= 10; 
  MainTitleLbl.Height = 65;
  MainTitleLbl.Width = 259;
}

{
  MainForm = TclForm.Create(Self);
  MainForm.BtnFormMenu.Visible = False;
  MainForm.FormWaiting.Visible = False;
  
  SetMainTitle;
  
  MainLyt = MainForm.AddNewLayout(MainForm,'MainLyt');
  MainLyt.Align=alClient;
  MainLyt.Margins.Bottom = 10;
  MainLyt.Margins.Top = 10;
  
  SetBigPanel;
  SetMiddlePanel;

  if (Clomosy.AppUserProfile == 1 )
  {
    SendButton.Enabled = True;
  }
  else
  {
    SendButton.Enabled = False;
    QuestionEdit.Text = 'Only the administrator can write.';
    QuestionEdit.Enabled = False;
  }

  MainForm.Run;
}

See Also