Sajya Server
repository·master·Indexed 42 days ago
https://github.com/sajya/serverA Laravel-based implementation of the JSON-RPC 2.0 protocol. It provides tools for full specification compliance, including automatic parameter validation, support for batch and notification requests, and a custom `rpc` route macro. Features include Artisan commands for scaffolding procedures (`make:procedure`) and generating HTML API documentation (`sajya:docs`), as well as flexible procedure resolution via delimiters and proxy fallbacks.
What's inside Sajya
- Sajya is a library for Laravel developers that enables the implementation of the JSON-RPC 2.0 specification. It provides tools to achieve full compliance with the JSON-RPC 2.0 spec, including automatic parameter validation, support for batch requests, and handling of notification requests (fire-and-forget).
How procedure resolution and proxies work
masterThe
Appclass resolves JSON-RPC methods by splitting the requested method string using the configureddelimiter(default@).Resolution Logic
- Direct Match: It looks for a registered
Procedureclass where the class'snameproperty matches the part before the delimiter, and the class has a public method matching the part after the delimiter. - Proxy Fallback: If no direct method match is found, the
Appsearches for a registered procedure that implements theSajya\Server\Proxyinterface. If found, it attempts to call the__invokemethod on that proxy class.
Example Method Mapping
If your delimiter is
@and you have a procedureUserProcedurewithname = 'user':- Request method
user@getProfile$\rightarrow$ callsUserProcedure::getProfile() - Request method
user@someUnknown$\rightarrow$ callsUserProcedure::__invoke()(ifUserProcedureimplementsProxy)
- Direct Match: It looks for a registered
Publish the Sajya configuration file
masterTo customize the behavior of the JSON-RPC server, you can publish the default configuration file to your application's
configdirectory.php artisan vendor:publish --tag=configPublish Sajya views
masterIf you need to customize the views used by the package, you can publish them to
resources/views/vendor/sajyausing theviewstag.php artisan vendor:publish --tag=viewsHandle InternalErrorException in JSON-RPC
masterThe
InternalErrorExceptionis a specific type ofRpcExceptionused to signal internal server errors within the JSON-RPC protocol. When this error is encountered, it follows the standard JSON-RPC error code for internal errors.Error Details:
- JSON-RPC Error Code:
-32603 - Default Message:
Internal error - Data: Can optionally contain additional error context via the
$dataparameter.
- JSON-RPC Error Code:
Handle InvalidParams exceptions
masterThe
Sajya\Server\Exceptions\InvalidParamsexception is thrown when request parameters fail validation. It is a specializedRpcExceptionthat follows the JSON-RPC error specification. When caught, it provides a standard error code and message.Error Details:
- Code:
-32602(Standard JSON-RPC code for 'Invalid params') - Message:
'Invalid params' - Data: Can contain additional context or details about the specific validation failure via the
$dataparameter.
- Code:
Manage JSON-RPC Request properties
masterThe
Requestclass provides fluent setter methods to configure the properties of a JSON-RPC request. Most setters return$thisto allow for method chaining.setMethod(string $name): Sets the name of the requested method.setParams(array $params): Merges new parameters into the existingparamscollection.setId($name): Sets the request identifier (cast to a string).setVersion(string $version): Sets the JSON-RPC version (defaults to'2.0').
use Sajya\Server\Http\Request; $request = (new Request()) ->setMethod('sum') ->setParams(['a' => 1, 'b' => 2]) ->setId(123) ->setVersion('2.0');Serialize a Request to JSON
masterThe
Requestclass implementsJsonSerializable. When serialized (e.g., viajson_encode()), it produces a JSON object containing thejsonrpcversion, themethod, and optionally theparamsandidif they are present.$request = (new Request())->setMethod('ping')->setId('abc'); echo json_encode($request); // Output: {"jsonrpc":"2.0","method":"ping","id":"abc"}Initialize the Sajya App
masterThe
Sajya\Server\Appclass is the main entrypoint for managing JSON-RPC requests. You initialize it by providing an array of procedure classes and an optional delimiter.Constructor Parameters
array $procedures: An array of class names. Each class must extendSajya\Server\Procedure.?string $delimiter: The character used to separate the procedure name from the method name in the JSON-RPCmethodstring. If not provided, it defaults to@or the value configured inconfig('sajya.delimiter').
If a class provided in
$proceduresdoes not extendProcedure, the application will abort with a 500 error.use Sajya\Server\App; // Initialize with specific procedures and a custom delimiter $app = new App([ App\Procedures\UserProcedure::class, App\Procedures\OrderProcedure::class, ], ':');Check if a request is a notification using isNotification()
masterIn JSON-RPC, a notification is a request that does not include an
id. You can determine if the currentRequestinstance is a notification by callingisNotification(), which returnstrueif the request ID is empty.if ($request->isNotification()) { // Handle as a notification (no response expected) }Terminate the application with terminate()
masterThe
terminate()method handles the request processing and then triggers the Laravel application termination process. This is useful for ensuring the JSON-RPC response is returned while allowing the underlying framework to clean up.Parameters
string $content: The raw JSON-RPC request content.
Returns
Sajya\Server\Http\Response[]|Sajya\Server\Http\Response|null
$app->terminate($request->getContent());Create a JSON-RPC response with makeFromResult()
masterThe
makeFromResult()static method is the primary way to instantiate aResponseobject. It automatically synchronizes the response'sidandversionwith the providedRequestobject, ensuring the response matches the incoming RPC call. If noRequestis provided, a new instance is created.use Sajya\Server\Http\Response; use Sajya\Server\Http\Request; // Assuming $result is the data you want to return $response = Response::makeFromResult($result, $request);