Skip to content

Commit

Permalink
add rpc
Browse files Browse the repository at this point in the history
  • Loading branch information
sagittaracc committed Nov 19, 2024
1 parent 4114d84 commit fa2f42c
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 7 deletions.
23 changes: 16 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,22 +98,31 @@ set_decorator_prop($progress, 'status', 'progress'); // status is one of possib
set_decorator_prop($progress, 'caption', 'in progress ...'); // just a string (max length is 32)
```

# Router
# Rpc
```php
use Sagittaracc\PhpPythonDecorator\Decorator;
use Sagittaracc\PhpPythonDecorator\modules\rpc\core\Rpc;

#[Rpc]
class Controller
{
use Decorator;

#[Route('/hello')]
#[Route('/hello/(\w+)')]
function greetingPerson($name = 'guest')
public function sum($a, $b)
{
return "Hello, $name";
return $a + $b;
}
}
```

in `index.php`

```php
// STUB
$requestBody = '{"id":1,"method":"sum","params":[1,2]}';

// index.php
(new Route('/hello/Yuriy'))->getMethod(Controller::class)->run(); // output: Hello, Yuriy
$controller = new Controller();
$controller($requestBody); // Output: {"json-rpc":"2.0","id":1,"result":3}
```

# Console
Expand Down
7 changes: 7 additions & 0 deletions src/exceptions/InvalidJsonException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Sagittaracc\PhpPythonDecorator\exceptions;

use Exception;

class InvalidJsonException extends Exception {}
7 changes: 7 additions & 0 deletions src/exceptions/ValidationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Sagittaracc\PhpPythonDecorator\exceptions;

use Exception;

class ValidationException extends Exception {}
36 changes: 36 additions & 0 deletions src/modules/rpc/JsonRpc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Sagittaracc\PhpPythonDecorator\modules\rpc;

use Sagittaracc\PhpPythonDecorator\modules\Module;

class JsonRpc extends Module
{
public static function parseError()
{
return json_encode(['error' => 'Parse error', 'code' => -32700]);
}

public static function invalidRequest()
{
return json_encode(['error' => 'Invalid request', 'code' => -32600]);
}

public static function methodNotFound()
{
return json_encode(['error' => 'Method not found', 'code' => -32601]);
}

public static function result($object, $request)
{
$id = $request->id;
$method = $request->method;
$params = $request->params;

return json_encode([
'json-rpc' => '2.0',
'id' => $id,
'result' => call_user_func_array([$object, $method], $params),
]);
}
}
40 changes: 40 additions & 0 deletions src/modules/rpc/core/Request.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace Sagittaracc\PhpPythonDecorator\modules\rpc\core;

use Exception;
use Sagittaracc\PhpPythonDecorator\Decorator;
use Sagittaracc\PhpPythonDecorator\exceptions\InvalidJsonException;
use Sagittaracc\PhpPythonDecorator\exceptions\ValidationException;
use Sagittaracc\PhpPythonDecorator\modules\validation\core\primitives\Number;
use Sagittaracc\PhpPythonDecorator\modules\validation\core\primitives\Str;

class Request
{
use Decorator;

#[Number]
public $id;

#[Str]
public $method;

public array $params;

function __construct($rawRequest)
{
$request = json_decode($rawRequest);

if ($request === null) {
throw new InvalidJsonException;
}

try {
set_decorator_prop($this, 'id', $request->id ?? null);
set_decorator_prop($this, 'method', $request->method ?? null);
set_decorator_prop($this, 'params', $request->params ?? []);
} catch (Exception $e) {
throw new ValidationException;
}
}
}
37 changes: 37 additions & 0 deletions src/modules/rpc/core/Rpc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Sagittaracc\PhpPythonDecorator\modules\rpc\core;

use Attribute;
use Sagittaracc\PhpPythonDecorator\exceptions\InvalidJsonException;
use Sagittaracc\PhpPythonDecorator\exceptions\ValidationException;
use Sagittaracc\PhpPythonDecorator\modules\rpc\JsonRpc;
use Sagittaracc\PhpPythonDecorator\PythonDecorator;

#[Attribute]
class Rpc extends PythonDecorator
{
public function wrapper(mixed $object)
{
return function (...$args) use ($object) {
try {
$error = false;
$request = new Request($args[0]);
} catch (InvalidJsonException $e) {
$error = true;
echo JsonRpc::parseError();
} catch (ValidationException $e) {
$error = true;
echo JsonRpc::invalidRequest();
}

if (!$error) {
if (!method_exists($object, $request->method)) {
echo JsonRpc::methodNotFound();
} else {
echo JsonRpc::result($object, $request);
}
}
};
}
}
22 changes: 22 additions & 0 deletions tests/RpcTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use Sagittaracc\PhpPythonDecorator\tests\examples\RpcController;

final class RpcTest extends TestCase
{
public function testRpc(): void
{
ob_start();

// STUB
$requestBody = '{"id":1,"method":"sum","params":[1,2]}';

$controller = new RpcController();
$controller($requestBody);

$this->assertSame('{"json-rpc":"2.0","id":1,"result":3}', ob_get_clean());
}
}
17 changes: 17 additions & 0 deletions tests/examples/RpcController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace Sagittaracc\PhpPythonDecorator\tests\examples;

use Sagittaracc\PhpPythonDecorator\Decorator;
use Sagittaracc\PhpPythonDecorator\modules\rpc\core\Rpc;

#[Rpc]
class RpcController
{
use Decorator;

public function sum($a, $b)
{
return $a + $b;
}
}

0 comments on commit fa2f42c

Please sign in to comment.