Installation
composer require agentsib/jsonrpc
Add to composer.json if not auto-discovered:
"autoload": {
"psr-4": {
"App\\": "app/",
"JsonRpc\\": "vendor/agentsib/jsonrpc/src/"
}
}
Run composer dump-autoload.
First Use Case: Basic RPC Server
Define a service class with @JsonRpcMethod annotations:
use JsonRpc\Annotations\JsonRpcMethod;
class CalculatorService {
/**
* @JsonRpcMethod
*/
public function add($a, $b) {
return $a + $b;
}
}
Register the service in a Laravel controller:
use JsonRpc\Server;
public function handleRpcRequest() {
$server = new Server();
$server->addService(new CalculatorService());
return $server->handleRequest($_POST['jsonrpc']);
}
First Use Case: Basic RPC Client
use JsonRpc\Client;
$client = new Client('http://your-endpoint');
$result = $client->call('CalculatorService.add', [1, 2]);
Laravel Service Container Bind services to the container for dependency injection:
$app->bind('JsonRpc\CalculatorService', function ($app) {
return new CalculatorService($app['logger']);
});
Register with the RPC server:
$server->addService($app->make('JsonRpc\CalculatorService'));
Middleware Integration Wrap RPC requests with Laravel middleware:
$server->setMiddleware(function ($request) {
$request->setUser(auth()->user());
return $request;
});
Custom Request Parsing Override default JSON parsing:
$server->setRequestParser(function ($raw) {
return json_decode($raw, true);
});
Response Transformation Modify responses before sending:
$server->setResponseTransformer(function ($response) {
return json_encode($response) . "\n";
});
Custom Error Responses
Extend JsonRpc\Exceptions\JsonRpcException:
class ValidationException extends JsonRpcException {
public function __construct($message, $errors) {
parent::__construct($message, -32602);
$this->errors = $errors;
}
}
Throw in methods:
if (!$valid) {
throw new ValidationException('Invalid input', ['field' => 'required']);
}
Global Exception Handler Attach to Laravel’s exception handler:
$server->setExceptionHandler(function ($e) {
report($e);
return $e->toJsonRpcResponse();
});
Token-Based Auth Validate tokens in middleware:
$server->setMiddleware(function ($request) {
if ($request->getHeader('Authorization') !== 'Bearer valid-token') {
throw new JsonRpcException('Unauthorized', -32601);
}
});
Laravel Auth Integration Use Laravel’s auth system:
$server->setMiddleware(function ($request) {
$request->setUser(auth()->guard('api')->user());
});
Annotation Parsing
Ensure doctrine/annotations is installed:
composer require doctrine/annotations
If annotations aren’t parsed, verify the JsonRpc\Annotations\Reader is initialized.
Circular References
Avoid circular references in responses (e.g., nested objects). Use JsonSerializable or custom serialization:
$server->setResponseTransformer(function ($response) {
return json_encode($response, JSON_THROW_ON_ERROR);
});
Thread Safety
The package isn’t thread-safe by default. For queues/jobs, instantiate a new Server per request.
Enable Logging Log raw requests/responses:
$server->setMiddleware(function ($request) {
logger()->debug('RPC Request', ['input' => $request->getData()]);
});
Validate JSON-RPC Spec Use tools like JSON-RPC Validator to test responses.
Custom Method Discovery
Override JsonRpc\Annotations\Reader to support non-annotation methods:
$reader = new CustomReader();
$server->setMethodReader($reader);
Batch Requests Enable batch processing:
$server->enableBatchMode();
Handle batches in middleware:
$server->setMiddleware(function ($request) {
if ($request->isBatch()) {
$request->setBatchProcessor(function ($batch) {
return array_map(fn($req) => $this->processSingle($req), $batch);
});
}
});
Route Caching Exclude RPC routes from route caching if they’re dynamic:
Route::middleware(['web', 'rpc'])->group(function () {
// RPC routes
});
Rate Limiting Apply Laravel’s throttling middleware:
$server->setMiddleware(function ($request) {
if (app('throttle')->tooManyAttempts($request->ip(), 60)) {
throw new JsonRpcException('Rate limit exceeded', -32003);
}
});
API Resources Transform RPC responses into API resources:
$server->setResponseTransformer(function ($response) {
return new JsonRpcResource($response);
});
How can I help you explore Laravel packages today?