Laravel NATSRPC Server
This package implements a JSON-RPC server over a NATS transport.
You can call methods on other services without changing your workflow too much
composer require dpniel_ch/laravel-natsrpc-server
Running the NATS-RPC Server
This package includes a server binary that manages the long lived connections with a nats server and offloads requests and events to a pool of
php workers it manages.
The php workers transform a nats-rpc payload into an Illuminate\Http\Request
and pass this off to laravels kernel to be handled by an \App\Nats\Controller
which has been configured in routes/nats.php
To run the server you need to create a config file for the natsrunner (or vendor:publish if laravel).
Create a file called config/natsrpc.php
in your project s config directory
<?php
return [
"service" => env("NATSRPC_SERVICE_NAME", "com.service.test"),
"server" => [
"command" => env("NATSRPC_WORKER_CMD", "php vendor/bin/natsrunner.php"),
"pool" => [
"num_workers" => env("NATSRPC_NUM_WORKERS", 5),
"max_jobs" => env("NATSRPC_MAX_JOBS", 100)
]
],
"nats" => [
"host" => env("NATS_HOST", "nats://127.0.0.1"),
"user" => env("NATS_USER", ""),
"pass" => env("NATS_PASS", "")
],
// String list of service names to event subscribe to.
"subscribe" => [
]
];
Once that's in place you can start the service with
$ php artisan nats:listen
If all is well you should now have a functioning server ready to accept requests through nats.
NatsRPC Controllers
$ php artisan make:nats-controller FooController
This will create a basic controller in app/Nats/Controllers with an index method. Now with Nats-RPC we just have to return an array of data
from the controller method which the calling route dispatcher will wrap into a JsonRpcResponse to send back.
// ...
class FooController
{
public function index(RequestParams $params)
{
// echo it back
return $params->all();
}
}
To make this controller accessable we need to bind it in the nats route file routes/nats.php
(You will need to create this)
// in routes/nats.php
// This binds all public controller methods to the given prefix of "foo"
// So calling "foo.bar" would call the bar function in the bound FooController.
$router->bindController("foo", "FooController");
// Or to bind just a single method
$router->bind("foo.index", "FooController@index");
NatsRPC Service Client
Now to call this method in the new controller above we can use the included NatsRPC Client.
use NatsRPC\Client\Service;
$service = Service::create("com.service.test"); // The service we want to talk to
$resp = $service->request("foo", ["test" => "data"]);
// Or
$resp = $service->request("foo.index", ["test" => "data"]);
if (!$resp->hasError() && $resp->hasResult()) {
dd($resp->result());
}
Broadcast Events over nats
You can either use the nats()
helper function to broadcast an event or get an instance of the NatsRPC Client and publish
nats("user.login", ["user" => $user->id]);
// Or
use NatsRPC\Client\Client;
app()->make(Client::class)->publish("user.login", [...])
Any service that is listening on a services events will fire a NatsRPC\Events\ServiceEvent
which applications can listen on and react to in the normal laravel Listener flow.