RPC-like API for your Laravel project
Tags: laravel, api, jsonrpc
Published: 2020-05-08 19:30:13

[JSON-RPC 2.0](https://www.jsonrpc.org/specification) this is a simple stateless **protocol** for creating an RPC (Remote Procedure Call) style API. It usually looks as follows:

You have one single endpoint on the server that accepts requests with a body of the form:

```json
{"jsonrpc": "2.0", "method": "post.like", "params": {"post": "12345"}, "id": 1}
```

And it returns answers of the view:

```json
{"jsonrpc": "2.0", "result": {"likes": 123}, "id": 1}
```

If an error occurs - the error response:

```php
{"jsonrpc": "2.0", "error": {"code": 404, "message": "Post not found"}, "id": "1"}
```

And it's all! Did I say that is easy?

Bonus support batch operations:

Request:
```json
[
   {"jsonrpc":"2.0","method":"server.shutdown","params":{"server":"42"},"id":1},
   {"jsonrpc":"2.0","method":"server.remove","params":{"server":"24"},"id":2}
]
```
Response:
```json
[
  {"jsonrpc":"2.0","result":{"status":"down"},"id":1}
  {"jsonrpc":"2.0","error":{"code":404,"message":"Server not found"},"id": 2}
]
```
In the id field, the API client can send anything so that after receiving responses from the server, match them with requests.

Also, the client can send “notifications” - requests without an “id” field that do not require a response from the server:

```json
{"jsonrpc":"2.0","method":"analytics:trackView","params":{"type": "post", "id":"123"}}
```

Not so long ago I became acquainted with this protocol, but it is great for my tasks of creating an API on Laravel. To use such a protocol in your application, you need to set the [dependency](https://sajya.github.io/) using the composer:

```php
$ composer require sajya/server
```

All actions are described in `Procedure` classes, it is a familiar controller, but it must contain the static property `name`.

Create the following artisan class:

```php
php artisan make:procedure TennisProcedure
```
A new file will be created in the `app/Http/Procedures/TennisProcedure.php`

Let's call the new procedure `tennis`, to do this, change the `name` property and add the `pong` returning value to the `ping` method to get this content:


```php
namespace App\Http\Procedures;

use Sajya\Server\Procedure;

class TennisProcedure extends Procedure
{
    /**
     * The name of the procedure that will be
     * displayed and taken into account in the search
     */
    public static string $name = 'tennis';

    /**
     * Execute the procedure.
     *
     * @return string
     */
    public function ping(): string
    {
        return 'pong';
    }
}
```

Like the controller, the procedure needs to be registered in the routes file, define it in the file `api.php`:

```php
use App\Http\Procedures\TennisProcedure;

Route::rpc('/v1/endpoint', [
    TennisProcedure::class
])->name('rpc.endpoint');
```


In order to turn to the required method, you must pass the name specified in the class and the necessary method with the delimiter "@" character. In our case, it will be: `tennis@ping`.

Let's make a `curl` call to the new API:

```bash
curl 'http://127.0.0.1:8000/api/v1/endpoint' --data-binary '{"jsonrpc":"2.0","method":"tennis@ping","params":[],"id" : 1}'
```

The result will be the resulting JSON string:
```bash
{"id":"1","result":"pong","jsonrpc":"2.0"}
```