[fpc-pascal] Improved FPC JSON-RPC support

Michael Van Canneyt michael at freepascal.org
Tue Dec 28 16:25:45 CET 2021


Hello,

Thanks to the magic of RTTI and Invoke(), creating a JSON-RPC server has
just become significantly easier !

Given an interface definition:

   IMyOtherInterface = interface ['{4D52BEE3-F709-44AC-BD31-870CBFF44632}']
     Function SayHello : string;
     function Echo(args : TStringArray) : String;
   end;

Creating a JSON-RPC server for this is now as simple as:

// Create a class that implements the interface
Type
   TIntf2Impl = class(TInterfacedObject, IMyOtherInterface)
   public
     function Echo(args: TStringArray): String;
     function SayHello: string;
   end;

function TIntf2Impl.Echo(args: TStringArray): String;

var
   S : String;

begin
   Result:='';
   For S in Args do
     begin
     if Result<>'' then
       Result:=Result+' ';
     Result:=Result+S;
     end
end;

function TIntf2Impl.SayHello: string;
begin
   Result:='Hello, World!';
end;

// Register the class using an interface factory:

Function GetMyOtherInterface(Const aName : string) : IInterface;

begin
   Result:=TIntf2Impl.Create as IInterface;
end;

initialization
   RTTIJSONRPCRegistry.Add(TypeInfo(IMyOtherInterface), at GetMyOtherInterface,'Service2');
end.


And calling it from a client program is even more simple:

var
   client: IMyOtherInterface;
   aRPCClient: TFPRPCClient;

begin
   // Register interface with name 'Service2'
   RPCServiceRegistry.Add(TypeInfo(IMyOtherInterface),'Service2');
   // Create client
   aRPCClient:=TFPRPCClient.Create(Nil);
   aRPCClient.BaseURL:='http://localhost:8080/RPC';

   // Just typecast the client to the desired interface
   Client:=aRPCClient as IMyotherInterface;

   // or explitly create using the registered service name
   // Client:=RPC.Specialize CreateService<IMyotherInterface>('Service2');

   Writeln('Sayhello: ',client.SayHello);
   Writeln('Sayhello: ',client.Echo(['This','is','Sparta']));
end.

The service can also be consumed by pas2js.

The support for various argument types is still limited, but this will improve soon.
Currently simple types and arrays of simple types are improved. Proper
support for records and other structured types needs extended RTTI...

An example server and client programs have been committed to the FPC repo.
(packages/fcl-web/examples/jsonrpc/rtti)

With many thanks to Sven Barth for putting me on the right track...

Enjoy!

Michael.


More information about the fpc-pascal mailing list