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 -------------------------------------}