Call Web Services and Data Parsing without Rest Libraries

Calling web APIs and data parsing is simple in Delphi XE5 through Rest libraries, but we can do this without Rest by creating a Unit (library) for it. As we all know to call any API with REST, we must have to work with three component initially i.e. RestClient, RestRequest (for executing service) and RestResponse ( to get JSON response ), but with help of this LtLiveConnector unit, we don’t require any kind of components on form and we are also able to execute all web services through it

To implement it, first add unit name in Uses under interface section of form code,Here we have Unit name as LtLiveConnector

Now, if you want to call web service on any button’s click then you can make use of unit as such:

 

 procedure TForm.ButtonClick(Sender: TObject);
 var Connector: LtLiveConnector.TLtLiveConnector;
 {-- To make use of library, we require to connect it, for connecting we add a variable as 
     Connector and to connect from with Unit, we pass “Unitname.ClassName” of Library --}
 Var _JSONString : string;
 Begin
 Connector:= TLtLiveConnector.Create(nil);
 Connector.Host:= fHost;
 Connector.Port:= fPort;
 Connector.NamePath:= fNamePath;
 try
   _JSONString := Connector.getJSON(Connector.Host, Connector.NamePath,’web service name’); 
   //_ JSONString := Connector.getJSON(NamePath,’web service name’);   
   //_ JSONString := Connector.getJSON(Host, NamePath, ‘webservice name’+’?aUserName=' +UserName +
   '&' + 'aPassword=' +Password);  //login call
 {-- here we have three different methods to call web services, and it will provide you string
     of JSON --}
 finally 
    Connector.Free;
 end;
 End;

 

Now we may get two kind of JSON:

  • First one, where we are getting JSON Object
  • Second one, where we are getting objects in form of array

 

How to parse object:

Suppose we have JSON object stored in variable _JSONString as;

 

      {
	“Employee Name”	: “Jigs”
	“Employer”	: “IT Organisation”
	“ID”		: “48”
      }


 

To parse this object take variables

 Var
 JO : TJSONObject;
 JP : TJSONPair;
 Str: string;
 Begin
 JO	:= TJSONObject.ParseJSONValue(_JSONString) as TJSONObject;
 JP	:= JO.Get(‘Employee Name’);
 Str	:= JP.JsonValue.Value;			{value in variable will be “Jigs”}

 MemoContent.Lines.Add(JP.ToString);	{value in Memo will be “Emplyee Name”:”Jigs”}
 MemoContent.Lines.Add(JP.JsonString.Value);	{value in Memo will be “Employee Name”}
 MemoContent.Lines.Add(JP.JsonValue.Value );	{value in Memo will be “Jigs”}
 END; 

 

How to parse objects of array:

Suppose we have JSON array stored in variable _JSONString as;

 [{
	“Employee Name”	: “AB”
	“Employer”	: “IT Organisation”
	“ID”		: “01”
 },
 {
	“Employee Name”	: “CD”
	“Employer”	: “IT Organisation”
	“ID”		: “02”
 }]


 

To parse this array take variables:

 Var
 JO : TJSONObject;
 JA : TJSONArray;
 JP : TJSONPair;
 JV : TJSONValue;
 Str: string;
 I  : Integer;

 Begin
 JV	   := TJSONObject.ParseJSONValue(_JSONString) as TJSONValue;
 JA	   := JV as TJSONArray;
 for i     := 0 to JA.Size - 1 do
 begin
 		JO := JA.Get(i) as TJSONObject;
 		JP := JO.Get(‘ID') as TJSONPair;
 MemoContent.Lines.Add(JP.JsonValue.Value );	
 end;
 End;

 {-- and value in MemoContent will be --}

 {------------------------------- Unit (Library )code starts ----------------------------------}
 unit LtLiveConnector;

 interface

 uses
  IDTCPClient,
  IdHeaderList,
  IdExceptionCore,
  IdGlobalProtocols,
  IdURI,
  DBXJSON,
  Datasnap.DBClient,
  DATA.DB,
  Web.HTTPApp,
  System.SysUtils,
  System.Types,
  System.Classes,
  System.UITypes;

 type

  THTTPVer = (HTTP1_0,HTTP1_1);
  TLtLiveConnector = class(TComponent)
  private
    { Private declarations }
    FKeepAlive  : Boolean;
    FRawRequest : String;
    FRawResponse: String;
    FHost       : String;
    FPort       : Integer;
    FSock       : TIDTCPClient;
    FHTTPVer    : THTTPVer;
    FNamePath   : String;
    FConfig     : String;
    procedure SetHost     (aHost: String);
    Procedure SetPort     (aPort: Integer);
    Procedure SetKeepAlive(aKeepAlive: Boolean);
    procedure SetConnected(aConnected: Boolean);
    procedure SetNamePath(aNamePath: String);
    procedure SetConfig(aConfig: String);
    function  GetConnected  :Boolean;
    function  HTTPVerText   :String;

  protected
    { Protected declarations }
  public
    { Public declarations }
    ResponseJSON: String;
    ResponseStream: TMemoryStream;
    Constructor Create( AOwner : TComponent ); override;
    Destructor Destroy; Override;
    Procedure GenerateJSON;
    //Procedure JSONToStringList(aJSONKey: String);
    function EncodeUrl(aDecodedUrl: String): String;
    function DecodeUrl(aEncodedUrl: String): String;
    function LiveGET(aRawHeader:String):String;
    function GetJSON(aNamePath, aCallAndParameters: String): String;overload;
    function GetJSON(aHost, aNamePath, aCallAndParameters: String): String;overload;
    function getJSON(aCallAndParameters: String): String;overload;
  published
    { Published declarations }
    Property Host           :String         Read FHost        Write SetHost;
    property Port           :Integer        Read FPort        Write SetPort       Default 80;
    property KeepAlive      :Boolean        Read FKeepAlive   Write SetKeepAlive  Default False;
    property Connected      :Boolean        Read GetConnected Write SetConnected;
    Property RawRequest     :String         Read FRawRequest  Write FRawRequest;
    Property RawResponse    :String         Read FRawResponse Write FRawResponse;
    property HTTPVersion    :THTTPVer       Read FHTTPVer     Write FHTTPVer;
    property NamePath       :String         Read FNamePath    Write SetNamePath;
    property Config         :String         Read FConfig      Write SetConfig;
  end;

 procedure Register;
 
  implementation

 //----------------------------------------------------------------------------//
 procedure Register;
 begin
 RegisterComponents('{Provide Name}', [TLtLiveConnector]);
 end;

 //----------------------------------------------------------------------------//
 <byte>Function StreamToArray(Strm:TStream):TArray </byte>;
 Begin
 Strm.Position := 0;
 SetLength(Result,Strm.Size);
 Strm.Read(Result[0],Strm.Size);
 End;

 //----------------------------------------------------------------------------//
 function StreamToString(aStream: TStream): string;
 var
   SS: TStringStream;
 begin
  if aStream <> nil then
  begin
    SS := TStringStream.Create('');
    try
      SS.CopyFrom(aStream, 0);
      Result := SS.DataString;
    finally
      SS.Free;
    end;
  end else
  begin
    Result := '';
  end;
 end;

 //----------------------------------------------------------------------------//

 function TLtLiveConnector.getJSON(aCallAndParameters: String): String;
 var
  zUrl: String;
 begin
  zUrl:= 'http://' + Host  + '/Node:' + NamePath + '.' + aCallAndParameters;
  try
  LiveGET(zUrl);
  GenerateJSON;
  result:= ResponseJSON;
  except
   result:= 'Hello ! Rahul is not returning any thing.';
  end;
 end;

 function TLtLiveConnector.getJSON(aNamePath, aCallAndParameters: String): String;
 var zUrl: String;

 begin

  zUrl:= 'http://' + Host  + '/Node:' + aNamePath + '.' + aCallAndParameters;
  try

  LiveGET(zUrl);

  GenerateJSON;
  result:= ResponseJSON;
  except
   result:= '';
   end;
 end;

 function TLtLiveConnector.getJSON(aHost, aNamePath, aCallAndParameters: String): String;
 var
  zUrl: String;
 begin
  zUrl:= 'http://' + aHost  + '/' + aNamePath + '.' + aCallAndParameters;
  try
  LiveGET(zUrl);
  GenerateJSON;
  result:= ResponseJSON;
  except
   result:= '';
  end;
 end;

 //----------------------------------------------------------------------------//
 Constructor TLtLiveConnector.Create(AOwner: TComponent);
 begin
  inherited;
  FPort     := 80;
  FHost     := ‘Domain Name’;
  FNamePath := ‘Path’;
  FSock     := TIDTCPClient.Create(Self);
  FSock.Port:= FPort;
  FSock.Host:= Fhost;
 end;

 //----------------------------------------------------------------------------//
 destructor TLtLiveConnector.Destroy;
 begin
  if FSock <> nil then
  begin
    FreeAndNil(FSock);
  end;
  inherited;
 end;

 //----------------------------------------------------------------------------//
 function TLtLiveConnector.HTTPVerText: String;
 begin
 Result := 'FUTURE HTTP VERSION !';
 if FHTTPVER = THTTPVER.HTTP1_0 then Result := '1.0';
 if FHTTPVER = THTTPVER.HTTP1_1 then Result := '1.1';
 end;

 //----------------------------------------------------------------------------//
 function TLtLiveConnector.EncodeUrl(aDecodedUrl: String): String;
 begin
  result:= tIdUri.URLEncode(aDecodedUrl);
 end;

 //----------------------------------------------------------------------------//
 function TLtLiveConnector.DecodeUrl(aEncodedUrl: String): String;
 begin
 result:= TIdURI.URLEncode(aEncodedUrl);
 end;

 //----------------------------------------------------------------------------//
 Procedure TLtLiveConnector.GenerateJSON;
 begin
 if ResponseStream <> nil then
  Begin
  responseJSON :=  StreamToString(responseStream);
  End;
 end;

 //----------------------------------------------------------------------------//

 function TLtLiveConnector.LiveGET(aRawHeader: String): String;
 begin
 if Not Connected then Connected := True;
 if Connected then
 begin
  FRawRequest :=  'GET /'+ EncodeUrl(aRawHeader) + ' HTTP/'+HTTPVerText+#13#10+
                  'Host: '+FHost+#13#10+

                  'Cookie: {supply user path name=supply user path value}; '+
                  '{supply user ID name=supply user ID value}; '+
                  '{supply login path name=supply login path value}; '+
                  ‘{supply all required paramaters}’+#13#10+

                  'Connection: Close'+#13#10+
                  #13#10;
  FSock.Socket.Write(FRawRequest);
  FRawResponse := FSock.Socket.ReadLn(#13#10#13#10,nil);
  Result := FRawResponse;
  if responseStream = nil then responseStream:= TMemoryStream.Create else
  ResponseStream.SetSize(0);
   FSock.Socket.ReadStream(ResponseStream,-1,True);
  if Connected and (Not KeepAlive) then Connected := False;
 end;
end;

 //----------------------------------------------------------------------------//
 procedure TLtLiveConnector.SetConnected(aConnected: Boolean);
 begin
 if aconnected <> FSock.Connected then
  if (aconnected) and (FHost <> '' )then FSock.Connect else FSOck.Disconnect;
end;

 //----------------------------------------------------------------------------//
 procedure TLtLiveConnector.SetHost(aHost: String);
 begin
 if aHost<>FHost then
  begin
  if Connected then Connected := False;
  FHost := aHost;
  FSock.Host := FHost;
  end;
 end;

 //----------------------------------------------------------------------------//
 procedure TLtLiveConnector.SetKeepAlive(aKeepAlive: Boolean);
 begin
 if aKeepAlive<>FKeepAlive then
  Begin
  if Connected then Connected := False;
  FkeepAlive := aKeepAlive;
  End;
 end;

 //----------------------------------------------------------------------------//
 procedure TLtLiveConnector.SetPort(aPort: Integer);
 begin
 if aPort<>FPort then
  begin
  if Connected then Connected := False;
  FPort := aPort;
  FSock.Port := FPort;
  end;
 end;

//----------------------------------------------------------------------------//
 procedure TLtLiveConnector.SetNamePath(aNamePath: String);
 begin
 if aNamePath <> FNamePath then
  FNamePath := aNamePath;
 end;

 //----------------------------------------------------------------------------//
 procedure TLtLiveConnector.SetConfig(aConfig: String);
 begin
 if aConfig <> FConfig then
   FConfig := aConfig;
 end;

 //----------------------------------------------------------------------------//
 function TLtLiveConnector.GetConnected: Boolean;
 begin
  Result := FSock.Connected;
 end;


 end.
 //----------------------------------------------------
 {---------------------------------- Unit (Library )code ends -------------------------------------}



Leave a comment