Passing Values to Arguments

When working with Sajya, you can easily pass values to the arguments in your handlers. This allows you to retrieve and use the data you need to perform specific actions.

Let’s consider an example where we want to subtract two values. In the JSON-RPC request, we pass the values a and b:

{
    "jsonrpc": "2.0",
    "method": "math@subtract",
    "params": {
        "a": 4,
        "b": 2
    },
    "id": 1
}

To access these values in the handler, you can use the Laravel Request object. Here’s an example implementation:

use Illuminate\Http\Request;

public function subtract(Request $request): int
{
    return $request->get('a') - $request->get('b');
}

Alternatively, you can leverage Sajya’s automatic argument binding feature. Simply define the argument types in the handler method signature, and Sajya will automatically bind the corresponding values based on their names. For example:

public function subtract(int $a, int $b): int
{
    return $a - $b;
}

This way, Sajya will automatically pass the values a and b as integers to the handler method.

Furthermore, if your request payload contains nested data, you can access it using camel case notation. Consider the following example where the params object has a nested property user with a name value:

{
    "jsonrpc": "2.0",
    "method": "....",
    "params": {
        "user": {
            "name": "Alex"
        }
    },
    "id": 1
}

To access the name value in your handler, you would define an argument with the same name in camel case:

public function handler(string $userName): string
{
    return $userName;
}

With this setup, Sajya will automatically bind the value "Alex" to the $userName argument in your handler method.

Customizing The Resolution Logic

If you wish to define your model binding resolution logic, you may use the RPC::bind method. The closure you pass to the bind method will receive the value of the params segment and should return the instance of the class that should be injected into the route. Again, this customization should take place in the boot method of your application’s RouteServiceProvider:

use Sajya\Server\Facades\RPC;
use Illuminate\Support\Facades\Route;

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    RPC::bind('a', function () {
        return 100;
    });
}

This will automatically replace the substituted value in our method:

public function subtract(int $a, int $b): int
{
    return $a - $b; // $a = 100
}

But at the same time, the request will contain the original value that was passed.

Explicit Model Binding

To register an explicit binding, use the RPC::model method to specify the class for a given parameter. It would help if you defined your explicit model bindings at the beginning of the boot method of your RouteServiceProvider class:

use Sajya\Server\Facades\RPC;
use Illuminate\Support\Facades\Route;

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    RPC::model('user', User::class);
}

It will work for anyone who expects a $user argument, and that value will be passed. The model will run the resolveRouteBinding method.

Deep binding

As with automatic substitution, bindings RPC::bind and RPC::model can be set for nested elements. To do this, you need to use the dot notation in the declaration. For example:

RPC::model('user.order', ...);
RPC::bind('user.order', ...;

In turn, this will expect camelCase in the arguments:

public function handler($userOrder)