Skip to main content

RPC Microservices

Nidus enables native socket-based RPC communication between services. A server publishes named handlers; clients invoke them by name over TCP.

Server side​

1. Choose a provider​

Two transport providers are included:

ProviderUnitNotes
IndyNidus.Server.IndyTRPCServerIndy
SynapseNidus.Server.SynapseTRPCServerSynapse

Both inherit from TRPCProviderServer (Nidus.RPC.Server).

2. Register and publish​

uses
Nidus,
Nidus.RPC.Server,
Nidus.Server.Indy; // or Nidus.Server.Synapse

var LServer: TRPCServerIndy;
begin
LServer := TRPCServerIndy.Create('0.0.0.0', 9900);

GetNidus
.UseRPC(LServer)
.PublishRPC('GetUser', TGetUserRPCResource)
.PublishRPC('CreateOrder', TCreateOrderRPCResource)
.Start(TAppModule.Create);
end;

UseRPC calls IRPCProviderServer.Start to begin listening. PublishRPC registers a name → TRPCResourceClass mapping in the TRPCRouteHandle registry.

3. Implement an RPC resource​

uses
Nidus.RPC.Resource;

type
TGetUserRPCResource = class(TRPCResource)
public
function Execute(const ARequest: string): string; override;
end;

function TGetUserRPCResource.Execute(const ARequest: string): string;
begin
// ARequest is the raw JSON payload sent by the client
Result := '{"id":1,"name":"Isaque"}';
end;

TRPCResourceClass = class of TRPCResource — defined in Nidus.RPC.Resource.

4. Dispatch (internal)​

TRPCRouteHandle.ExecuteRPC(ARequest) parses the request (via TRPCParse), looks up the registered class by name, instantiates it, calls Execute, and returns the result string.

Client side​

uses
Nidus.RPC.Client,
Nidus.Client.Indy; // or Nidus.Client.Synapse

var LClient: TRPCClientIndy;
begin
LClient := TRPCClientIndy.Create('127.0.0.1', 9900);
try
var LResponse := LClient.ExecuteRPC('{"rpc":"GetUser","payload":{"id":1}}');
// process LResponse
finally
LClient.Free;
end;
end;

TRPCProviderClient.ExecuteRPC is the abstract base; TRPCClientIndy / TRPCClientSynapse provide the actual TCP transport.

JSON envelope (confirmed from Nidus.RPC.Parse and Nidus.RPC.RouteHandle):

Request sent to the server:

{ "id": "1", "method": "MethodName", "params": ["arg1", "arg2"] }

Success response:

{ "jsonrpc": "2.0", "result": <return_value>, "id": "1" }

Error response (method not found):

{ "jsonrpc": "2.0", "error": { "code": -32601, "message": "Method MethodName not found" }, "id": "1" }

Unpublishing​

// via TRPCPublish directly (if you hold a reference)
LPublish.UnPublishRPC('GetUser');

Source: Nidus.RPC.Publish — TRPCPublish.UnPublishRPC.

Architecture​

TNidus.UseRPC(IRPCProviderServer)
└── IRPCProviderServer.Start (Indy / Synapse TCP listener)

TNidus.PublishRPC(name, class)
└── IRPCProviderServer.PublishRPC
└── TRPCRouteHandle.PublishRPC
└── TRPCPublish registry (name → TRPCResourceClass)

Incoming TCP request
└── TRPCProviderServer.ExecuteRPC(raw)
└── TRPCRouteHandle.ExecuteRPC
└── TRPCParse → name lookup → TRPCResource.Execute