JSON-RPC 2.0 API server for @Laravel framework

Overview

Laravel JSON RPC

Latest Version on Packagist GitHub Tests Action Status codecov Total Downloads

Introduction

Sajya is an open-source project aiming to implement the JSON-RPC 2.0 server specification for the Laravel quickly.

Some features:

  • Quick and straightforward route adding
  • Validation of parameters and custom messages
  • Support batch requests
  • Support notification requests

Official Documentation

Documentation for Sajya can be found on its website.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Maintainers

Sajya is developed and maintained by Alexandr Chernyaev.

License

The MIT License (MIT). Please see License File for more information.

Comments
  • request->id validation and request->method delimiter

    request->id validation and request->method delimiter

    Hello @tabuna Thanks for this awesome package!

    I have two simple questions

    1. According to the specification, id in RPC request described as
    id
    An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is not included it is assumed to be a notification. The value SHOULD normally not be Null [1] and Numbers SHOULD NOT contain fractional parts [2]
    The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects.
    
    [1] The use of Null as a value for the id member in a Request object is discouraged, because this specification uses a value of Null for Responses with an unknown id. Also, because JSON-RPC 1.0 uses an id value of Null for Notifications this could cause confusion in handling.
    
    [2] Fractional parts may be problematic, since many decimal fractions cannot be represented exactly as binary fractions.
    

    What is the reason for the current validation rule, which is

    'id'      => 'regex:/^\d*(\.\d{2})?$/|nullable',
    
    1. method delimiter How can I change default @ to the . (dot) or : (colon)?
    opened by vanodevium 8
  • Result for call in batchmode combined with notification

    Result for call in batchmode combined with notification

    I am experiencing issues combining a notification and a call in the same batch.

    I expected to get one result, ( id 1 ) and no response for the notification at all. Below you can see 2 tests, the first test gets 2 responses for each call. The second is the same, except for the last in the batch, its a notification without id. it shouldn't give a response. but the first in the batch should.

    Am i missing something here?

    Test without notification:

    $ curl -s 'http://127.0.0.1:80/api/v1' --data-binary '[{"jsonrpc":"2.0","method":"Resource@get","params":{"id":2},"id":1}, "jsonrpc":"2.0","method":"Resource@get","params":{"id":2},"id":1}]' | jq
    [
      {
        "id": "1",
        "result": {
          "id": 2,
          "name": "Dr. Sheldon Nikolaus",
          "attribute1": "morgMoa64F",
          "attribute2": "Dh3dN11Jbf",
          "created_at": "2021-08-13T12:39:49.000000Z",
          "updated_at": "2021-08-13T12:39:49.000000Z"
        },
        "jsonrpc": "2.0"
      },
      {
        "id": "1",
        "result": {
          "id": 2,
          "name": "Dr. Sheldon Nikolaus",
          "attribute1": "morgMoa64F",
          "attribute2": "Dh3dN11Jbf",
          "created_at": "2021-08-13T12:39:49.000000Z",
          "updated_at": "2021-08-13T12:39:49.000000Z"
        },
        "jsonrpc": "2.0"
      }
    ]
    

    Test with notification:

    $ curl -s 'http://127.0.0.1:80/api/v1' --data-binary\
     '[{"jsonrpc":"2.0","method":"Resource@get","params":{"id":2},"id":1},{"jsonrpc":"2.0","method":"Resource@get","params":{"id":2}}]' | jq
    [
      {
        "id": "1",
        "result": null,
        "jsonrpc": "2.0"
      },
      {
        "id": null,
        "result": null,
        "jsonrpc": "2.0"
      }
    ]
    
    opened by Wuffz 7
  • adding params to request give me an error

    adding params to request give me an error

    Hi, as described in the example on the docs all works for basic, but if I add some params to curl request, ive an error that i cannot understand:

    {"id":null,"error":{"code":-32700,"message":"Parse error","data":null,"file":"/home/natty/workspace/farmacie/vendor/sajya/server/src/Http/Parser.php","line":133,"trace":"#0 /home/natty/workspace/farmacie/vendor/sajya/server/src/Http/Parser.php(104): Sajya\Server\Http\Parser->checkValidation()\n#1 /home/natty/workspace/farmacie/vendor/sajya/server/src/Guide.php(49): Sajya\Server\Http\Parser->makeRequests()\n#2 /home/natty/workspace/farmacie/vendor/sajya/server/src/JsonRpcController.php(27): Sajya\Server\Guide->handle()\n#3 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(48): Sajya\Server\JsonRpcController->__invoke()\n#4 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Route.php(255): Illuminate\Routing\ControllerDispatcher->dispatch()\n#5 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Route.php(197): Illuminate\Routing\Route->runController()\n#6 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Router.php(691): Illuminate\Routing\Route->run()\n#7 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\Routing\Router->Illuminate\Routing\{closure}()\n#8 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#9 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Routing\Middleware\SubstituteBindings->handle()\n#10 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(127): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#11 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(103): Illuminate\Routing\Middleware\ThrottleRequests->handleRequest()\n#12 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(55): Illuminate\Routing\Middleware\ThrottleRequests->handleRequestUsingNamedLimiter()\n#13 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Routing\Middleware\ThrottleRequests->handle()\n#14 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#15 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Router.php(693): Illuminate\Pipeline\Pipeline->then()\n#16 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Router.php(668): Illuminate\Routing\Router->runRouteWithinStack()\n#17 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Router.php(634): Illuminate\Routing\Router->runRoute()\n#18 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Routing/Router.php(623): Illuminate\Routing\Router->dispatchToRoute()\n#19 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(166): Illuminate\Routing\Router->dispatch()\n#20 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}()\n#21 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#22 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()\n#23 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#24 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()\n#25 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#26 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle()\n#27 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(87): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#28 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()\n#29 /home/natty/workspace/farmacie/vendor/fruitcake/laravel-cors/src/HandleCors.php(57): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#30 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\Cors\HandleCors->handle()\n#31 /home/natty/workspace/farmacie/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#32 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\Proxy\TrustProxies->handle()\n#33 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()\n#34 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(141): Illuminate\Pipeline\Pipeline->then()\n#35 /home/natty/workspace/farmacie/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()\n#36 /home/natty/workspace/farmacie/public/index.php(52): Illuminate\Foundation\Http\Kernel->handle()\n#37 /home/natty/workspace/farmacie/server.php(21): require_once('/home/natty/wor...')\n#38 {main}"},"jsonrpc":"2.0"}

    opened by jahstation 6
  • Feature/error reporting

    Feature/error reporting

    1. #38 Finally, I figured out that it's not necessarily rendering exception with error handler. Expected exceptions need to transform must extend RpcException. What I need is just error reporting.
    2. All exceptions will be caught by Exception, these is no need to catch HttpException or RuntimeException.
            } catch (HttpException | RuntimeException | Exception $exception) {
    

    origin code

    opened by pawmaster 4
  • [Discussion] Should we remove the assumed assertOk() in ProceduralRequests trait?

    [Discussion] Should we remove the assumed assertOk() in ProceduralRequests trait?

    Consider this use case:

    Authentication happens in headers with api tokens. I'd like to test through a procedure call attempt, that the headers successfully require auth, and thus return a 401 HTTP code.

    I know I could bypass the trait methods and make my own setup that rips out the assertOk, but specifically I'd like to use the original callProcedure method to test all my procedures. It would just be nice if I could use the same calling of a procedure test, to test the auth for the procedure routes as well.

    Maybe enlighten me if I am missing a bit of the philosophy behind this. I understand that jrpc must return http 200, and error key for application errors. However I thought it is reasonable to want to test the procedure call, and fail auth, and thus have a http response code that is not 200 (this is not a failure/error or mistake of JRPC, but of the authentication in the headers trying to POST to hit a procedure).

    Please let me know! I didn't make the PR yet just because I wanted to see & understand if it was a desired change for the package.

    opened by SimonMacIntyre 4
  • JSON-RPC forwarding

    JSON-RPC forwarding

    Let's try to imagine a proxy service that receives a request or requests as input and forwards them to other third-party services, depending on the request parameters. As a result, it returns a list of responses that third-party services returned.

    Some example of idea:

    Input request into RPC-proxy:

    [
      {
        "jsonrpc": "2.0",
        "method": "service1:procedure@sum", // this request will be forwarded to the service1 as procedure@sum
        "params": [
          1,
          2,
          3
        ],
        "id": 2
      },
      {
        "jsonrpc": "2.0",
        "method": "service2:procedure@avg", // this request will be forwarded to the service2 as procedure@avg
        "params": [
          1,
          2,
          3
        ],
        "id": 3
      },
      {
        "jsonrpc": "2.0",
        "method": "service3:procedure@min, // this request will be forwarded to the service3 as procedure@min,
        "params": [
          1,
          2,
          3
        ],
        "id": 4
      }
    ]
    

    And response from RPC-proxy:

    [
      {
        "id": "2",
        "result": {"sum":6}, // this is response from the service1 for procedure@sum
        "jsonrpc": "2.0",
        "method": "procedure@sum"
      },
      {
        "id": "3",
        "result": {"avg":2}, // this is response from the service2 for procedure@avg
        "jsonrpc": "2.0",
        "method": "procedure@avg"
      },
      {
        "id": "4",
        "result": {"min":1}, // this is response from the service3 for procedure@min,
        "jsonrpc": "2.0",
        "method": "procedure@min"
      }
    ]
    

    The main question is this: is it possible to parse all input requests using the Sajya\Server\Http\Parser and forward them through the Guzzle as is?

    Maybe you can give some advice or point me in the right direction?

    opened by vanodevium 4
  • php artisan route:clear command throws InvalidArgumentException

    php artisan route:clear command throws InvalidArgumentException

    whenever I try to clear the route caches with rpc endpoint, i get the InvalidArgumentException exception

    
       InvalidArgumentException 
    
      Attribute [rpc] does not exist.
    
      at vendor/laravel/framework/src/Illuminate/Routing/RouteRegistrar.php:107
        103▕      */
        104▕     public function attribute($key, $value)
        105▕     {
        106▕         if (! in_array($key, $this->allowedAttributes)) {
      ➜ 107▕             throw new InvalidArgumentException("Attribute [{$key}] does not exist.");
        108▕         }
        109▕ 
        110▕         if ($key === 'middleware') {
        111▕             foreach ($value as $index => $middleware) {
    
          +2 vendor frames 
      3   routes/api.php:28
          Illuminate\Support\Facades\Facade::__callStatic()
    
          +4 vendor frames 
      8   app/Providers/RouteServiceProvider.php:46
          Illuminate\Routing\RouteRegistrar::group()
    
    opened by nizigama 3
  • Internal exception when procedure method not exists

    Internal exception when procedure method not exists

    When calling to a method which procedure doesn't have, it turns out into an internal exception.

    local.ERROR: Method App\Http\Procedures\TennisProcedure::pinga() does not exist {"exception":"[object] (ReflectionException(code: 0): Method App\Http\Procedures\TennisProcedure::pinga() does not exist at /app/vendor/sajya/server/src/Guide.php:144)

    Procedure Class

    <?php
    declare(strict_types=1);
    
    namespace App\Http\Procedures;
    
    use Illuminate\Http\Request;
    use Sajya\Server\Procedure;
    
    class TennisProcedure extends Procedure
    {
        public static string $name = 'tennis';
    
        public function ping(): string
        {
            return 'pong';
        }
    }
    

    Call a method not exists

    <?php
    namespace App\Http\Controllers;
    use Illuminate\Support\Facades\Http;
    use Sajya\Client\Client;
    
    class TennisController extends Controller
    {
        public function index(): mixed
        {
            $request = Http::withoutVerifying()
                ->baseUrl(route('rpc.endpoint'));
            $client = new Client($request);
            $response = $client->execute('tennis@pinga');
            return $response->result();
        }
    }
    
    opened by pawmaster 2
  • Bump actions/cache from 3.0.11 to 3.2.1

    Bump actions/cache from 3.0.11 to 3.2.1

    Bumps actions/cache from 3.0.11 to 3.2.1.

    Release notes

    Sourced from actions/cache's releases.

    v3.2.1

    What's Changed

    Full Changelog: https://github.com/actions/cache/compare/v3.2.0...v3.2.1

    v3.2.0

    What's Changed

    New Contributors

    Full Changelog: https://github.com/actions/cache/compare/v3...v3.2.0

    v3.2.0-beta.1

    What's Changed

    v3.1.0-beta.3

    What's Changed

    • Bug fixes for bsdtar fallback, if gnutar not available, and gzip fallback, if cache saved using old cache action, on windows.

    Full Changelog: https://github.com/actions/cache/compare/v3.1.0-beta.2...v3.1.0-beta.3

    ... (truncated)

    Changelog

    Sourced from actions/cache's changelog.

    3.0.11

    • Update toolkit version to 3.0.5 to include @actions/core@^1.10.0
    • Update @actions/cache to use updated saveState and setOutput functions from @actions/core@^1.10.0

    3.1.0-beta.1

    • Update @actions/cache on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. (issue)

    3.1.0-beta.2

    • Added support for fallback to gzip to restore old caches on windows.

    3.1.0-beta.3

    • Bug fixes for bsdtar fallback if gnutar not available and gzip fallback if cache saved using old cache action on windows.

    3.2.0-beta.1

    • Added two new actions - restore and save for granular control on cache.

    3.2.0

    • Released the two new actions - restore and save for granular control on cache

    3.2.1

    • Update @actions/cache on windows to use gnu tar and zstd by default and fallback to bsdtar and zstd if gnu tar is not available. (issue)
    • Added support for fallback to gzip to restore old caches on windows.
    • Added logs for cache version in case of a cache miss.
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 1
  • Update vimeo/psalm requirement from ^4.6 to ^5.1

    Update vimeo/psalm requirement from ^4.6 to ^5.1

    Updates the requirements on vimeo/psalm to permit the latest version.

    Release notes

    Sourced from vimeo/psalm's releases.

    5.1.0

    What's Changed

    Deprecations

    Features

    Fixes

    Docs

    New Contributors

    Full Changelog: https://github.com/vimeo/psalm/compare/5.0.0...5.1.0

    Commits
    • 4defa17 Merge pull request #8774 from bdsl/report-by-issue-type-severity
    • 1dbdf78 Code style fix
    • ad57727 Sort issue by position in codebase in ByIssueLevelAndTypeReport if level & ty...
    • a29f65e Fix too lax function visibility in test
    • 6693421 Code style fix
    • 5423983 Fix error in ByIssueLvelAndTypeReport heading
    • 699ee34 Indent heredoc in test
    • d6c7c86 Remove unecassary subheadings in error levels documentation
    • cd18cdc Re-order list of errors in docs
    • 9e63bf6 Minor code edits in ByIssueLevelAndType
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies php 
    opened by dependabot[bot] 1
  • PHPUnit 9 Shift

    PHPUnit 9 Shift

    This pull request contains changes for upgrading to PHPUnit 9 automated by the PHPUnit 9 Shift.

    Before merging, you should review all comments and commit any changes to the shift-75073 branch.

    If there were changes you felt could have been automated, please reply to the follow-up email with your feedback or on Twitter.

    opened by tabuna 1
  • Overwrite Method name ?

    Overwrite Method name ?

    Hi , Thanks for your work !

    I'm using your package for simulate another rpc-endpoint , like i have another system who send json rpc request with method "ping" but since the method start with producer name its fail with

     "error": {
        "code": -32601,
        "message": "Method not found",
    

    I have try to overwrite the method name by middleware like this

    
    use Illuminate\Http\Request
     public function handle(Request $request, Closure $next)
        {
            $input = $request->all();
            Log::info("Request method ", [$input["method"], $request->method]); // Shows original request
            $request->merge([
                'method' =>  "message@" . $input['method']
            ]);
            $input = $request->all();
            $request->setMethod("message@" . $input['method']);
            Log::info("After Request method ", [$input["method"], $request->method]); // Shows modified request
    
    
    
    
            return $next($request);
        }
    

    Bur i think its been ignored at all ..

    Do you have any clues ?

    Thanks

    opened by m7mdcc 1
  • [Enhancement]Support for framework exception handler

    [Enhancement]Support for framework exception handler

    All exceptions are catched by Sajya\Server\HandleProcedure::handle without reporting. It will be a better way to use Illuminate\Contracts\Debug\ExceptionHandler to deal with exceptions.

    As a benifit of this, all exceptions will be reported, such as logging and instant messaging, most useful for debugging. On the other hand, we can transform them into json-rpc format.

    opened by pawmaster 1
  • [Feature Request]Dynamic procedure name support

    [Feature Request]Dynamic procedure name support

    Maybe procedure name can be set from class name and relative namespace.

    <?php
    
    declare(strict_types=1);
    
    namespace Sajya\Server;
    
    use Illuminate\Support\Str;
    
    abstract class Procedure
    {
        public static function guessProcedureName(): string
        {
            return Str::snake(substr(class_basename(static::class), 0, -strlen('Procedure')));
        }
    
    opened by pawmaster 0
  • it don't work with quickstart,  it return 404 not found, my route not correct ?

    it don't work with quickstart, it return 404 not found, my route not correct ?

    class TennisProcedure extends Procedure
    {
        /**
         * The name of the procedure that will be
         * displayed and taken into account in the search
         *
         * @var string
         */
        public static string $name = 'tennis';
    
        /**
         * Execute the procedure.
         *
         * @param Request $request
         *
         * @return array|string|integer
         */
        public function ping(Request $request)
        {
            return "pong";
        }
    }
    

    and my route in api.php

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

    and my request:

    request url:
    http://127.0.0.1:8006/api/v1/endpoint
    
    request  body
    {
        "jsonrpc": "2.0",
        "method": "tennis@ping",
        "id": 1
    }
    
    opened by weishuiliang 1
  • Problem with request with big payload

    Problem with request with big payload

    Smaller request works well, but larger ones (10MB+ payload, for example large email sets) hangs on processing side. The problem caused by the Arr::dot() call in \Sayja\Server\Binding bindResolve() function line 76

    opened by tocsa 2
  • Parameter model binding to resolve method dependencies

    Parameter model binding to resolve method dependencies

    Introduction

    I've been a bit disappointed to loose the ability to automatically bind method parameters based on the requests. With a REST-ish interface Laravel provides the Route Model Binding feature, which makes it convenient to just type-hint models on the controller methods, and let them be automatically resolved and injected to be used. I could see an explicit mention of a workaround in the documentation, but I wanted to achieve something which provides a more elegant syntax to do it so.

    Considerations

    I've been looking at how the default Route Model Binding works and tried to achieve a similar level of convenience, however since with the RPC route definition all Procedure classes are listed together, defining the parameter bindings in the route files would create convoluted and hard to read syntax. Also while the default Route Model Binding provides the Route::model() and the Route::bind() methods, they require the registration of a new Service and Facade accessors and I wanted to keep the solution to minimal and to implement with adding the least overhead to the library.

    Solution

    Since the official recommentation to work around the problem was already to use custom FormRequest instances on the Procedure methods, I think it is kind of easy to add the additional binding definitions there too. This way the implementer gets the full control over how to resolve the custom parameters, but can rely on the service container to help with the binding and after all simply just type hint what they need on the Procedure methods.

    The entry point of the solution is the HandleProcedure::handle() method, where I've replaced App::call($this->procedure); with BoundMethod::call(app(), $this->procedure); which is pretty much the same, however by this change we can extend the \Illuminate\Container\BoundMethod::addDependencyForCallParameter() with the custom logic needed to inject the parameters.

    The only catch is that the FormRequest parameter must come before any of the type hinted parameters that need custom resolution logic to apply. This is because addDependencyForCallParameter() resolves the parameters in the order they are needed for the Procedure method. So the first parameter is a FormRequest (or in fact any class) that implements the new BindsParameters Interface. During the resolution of the subsequent parameters, addDependencyForCallParameter() first checks each previously resolved parameters if they implement the BindsParameters Interface, and if so, uses them for the resolution. If there is no such parameters or no matches to be resolved, it passes the resolution back to parent::addDependencyForCallParameter() ensuring the implementation stays compatible with the original behaviour, if someone does not use custom FormRequests or the BindsParameters Interface.

    Now the BindsParameters Interface defines two methods to be used for the resolution.

    • resolveParameter() is the "replacement" for Route::bind(). It receives the name of the argument of the Procedure method, and expects the dependency instance to be returned. False can be returned to indicate to proceed with the rest of the resolution methods. null can be also used, if the parameter is optional.
    • getBindings() is the "replacement" for the default Implicit Binding. Since the Route files do not define how request parameters corresponds to Model parameters, "implicit" binding is not possible: it must be explicit. On the other hand, while Route::model() really matches the route parameters to Model types, in our case this is not needed, since the Model type can always be determined by the type hint on the Procedure method. What we need instead is a way to explicitly specify which parameters of the RPC request correspond to which parameter of the Processor method: the getBindings() therefore should return an array mapping the Processor method parameters to the RPC request parameters. The resolution follows the same logic as for route parameters. By default the request parameter is expected to contain a primary key (id or whatever is defined as the key of the given Model), or may contain other keys, in the same fashion as for route model binding using custom keys; the parameter and the key separated using a colon, e.g.: post:slug.

    Resolution by resolveParameter() takes precedence over resolution based on the getBindings(), and getBindings() takes precedence over the default resolution by the service container.

    Note

    Since any parameter that implements the BindsParameters interface can resolve subsequent dependencies, it is also possible to use a separate Request or FormRequest and another dependency of a BindsParameters class, effectively separating the Request from the Resolution, but this is more like a sideefect than a feature, tho someone may find it useful to use different FormRequest casses with the same BindsParametersClass or using the same FormRequest with a different BindsParametersClass for different methods.

    Examples

    You can find the tests in the PR, which indicates how to use the bindings:

    • FixtureRequest demonstrates the implementation of BindsParameters::getBindings() and BindsParameters::resolveParameter().
    • FixtureProcedure has been extended with few new getUserName... methods, which utilise the parameter resolution (and suit the test cases).

    In the Test cases I've user the Illuminate\Foundation\Auth\User as the type to be resolved to avoid adding an additional fixture class to the library just for the tests' sake.

    Questions

    Error codes

    I've read the error code section of the JSON:RPC documentation, but couldn't truly figure out what the ranges really mean. I came to the conclusion that the library implementing the standard may use the codes between -32000 to -32099 so I've assigned few of those in the new BoundMethod class to various resolution issues, but please advice if this usage is correct or should it use different codes?

    Documentation

    The contribution guide says documentation is expected with patches, but would that mean to submit a separate PR against the https://github.com/sajya/sajya.github.io repo with the documentation?


    Please let me know what do you think. I hope you find the addition useful! Let me know if something should be changed!

    opened by BenceSzalai 9
Releases(5.3.0)
  • 5.3.0(Nov 6, 2022)

    5.3.0 - 2022-11-06

    Added

    • Proxy procedure #47
    • Usage Laravel Pint for code style #46
    • Suggest client

    Changed

    • Improve typing
    • Update Bootstrap version for docs

    What's Changed

    • Bump actions/checkout from 2 to 3 by @dependabot in https://github.com/sajya/server/pull/43
    • Bump actions/cache from 2 to 3.0.11 by @dependabot in https://github.com/sajya/server/pull/44
    • Bump codecov/codecov-action from 2 to 3 by @dependabot in https://github.com/sajya/server/pull/42
    • Added usage Laravel Pint for code style by @tabuna in https://github.com/sajya/server/pull/46
    • Added Proxy procedure by @tabuna in https://github.com/sajya/server/pull/47

    New Contributors

    • @dependabot made their first contribution in https://github.com/sajya/server/pull/43

    Full Changelog: https://github.com/sajya/server/compare/5.2.0...5.3.0

    Source code(tar.gz)
    Source code(zip)
  • 5.2.0(Sep 2, 2022)

  • 5.1.0(Jul 19, 2022)

    5.1.0 - 2022-07-19

    Added

    • Added callHttpProcedure method which calls the procedure without any chained assertions #37

    New Contributors

    • @SimonMacIntyre made their first contribution in https://github.com/sajya/server/pull/37

    Full Changelog: https://github.com/sajya/server/compare/5.0.3...5.1.0

    Source code(tar.gz)
    Source code(zip)
  • 5.0.3(Jul 12, 2022)

  • 5.0.2(Jul 12, 2022)

  • 5.0.1(Apr 25, 2022)

  • 5.0.0(Feb 10, 2022)

    What's Changed

    • Added tests/Expected for a large file by @tabuna in https://github.com/sajya/server/pull/31
    • Minimum version of Laravel 9.x

    Full Changelog: https://github.com/sajya/server/compare/4.0.6...5.0.0

    Source code(tar.gz)
    Source code(zip)
  • 4.0.6(Jan 24, 2022)

  • 4.0.5(Jan 21, 2022)

    4.0.5 - 2022-01-21

    Changed

    • Parser: isAssociative() optimization #28
    • Added static method makeFromResult() #30

    What's Changed

    • Parser: isAssociative() optimization by @webdevium in https://github.com/sajya/server/pull/28
    • Response: static method makeFromResult() by @webdevium in https://github.com/sajya/server/pull/30

    Full Changelog: https://github.com/sajya/server/compare/4.0.4...4.0.5

    Source code(tar.gz)
    Source code(zip)
  • 4.0.4(Dec 26, 2021)

    4.0.4 - 2021-12-26

    Added

    • Tests for PHP 8.1
    • New terminate method for to execute pending tasks

    Full Changelog: https://github.com/sajya/server/compare/4.0.3...4.0.4

    Source code(tar.gz)
    Source code(zip)
  • 4.0.3(Oct 22, 2021)

  • 4.0.2(Aug 20, 2021)

  • 4.0.1(Aug 17, 2021)

  • 4.0.0(Aug 17, 2021)

  • 3.0.0(Apr 1, 2021)

  • 2.4.0(Feb 12, 2021)

  • 2.3.0(Feb 5, 2021)

  • 2.2.0(Jan 13, 2021)

  • 2.1.0(Nov 27, 2020)

  • 2.0.0(Sep 8, 2020)

  • 1.1.0(Aug 17, 2020)

  • 0.0.2(Mar 23, 2020)

  • 0.0.1(Mar 22, 2020)

Owner
Sajya
JSON-RPC API server for Laravel framework
Sajya
Lightweight JSON:API resource for Laravel

JSON:API Resource for Laravel A lightweight Laravel implementation of JSON:API. This is a WIP project currently being built out via livestream on my Y

Tim MacDonald 241 Jan 5, 2023
JSON:API for Laravel applications

JSON:API for Web Artisans Implement feature-rich JSON:API compliant APIs in your Laravel applications. Build your next standards-compliant API today.

Laravel JSON:API 330 Dec 26, 2022
Renders consistent HTTP JSON responses for API-based projects

Laravel API Response is a package that helps to provide and render a consistent HTTP JSON responses to API calls as well as converting and formatting

Kennedy Osaze 43 Nov 20, 2022
Builds nice, normalized and easy to consume REST JSON responses for Laravel powered APIs.

REST API Response Builder for Laravel Master branch: Development branch: Table of contents Introduction Why should I use it? Usage examples Features E

Marcin Orlowski 614 Dec 26, 2022
🔐 JSON Web Token Authentication for Laravel & Lumen

Documentation Documentation for 1.* here For version 0.5.* See the WIKI for documentation. Supported by Auth0 If you want to easily add secure authent

Sean Tymon 10.7k Jan 3, 2023
⚙️Simple key/value typed settings for your Laravel app with synchronized json export

Simple key/value typed settings for your Laravel app Create, store and use key/value settings, typed from numbers over dates to array, cached for quic

elipZis 8 Jan 7, 2023
Source code behind the Laracasts Larabit: Using MySQL JSON Columns with Laravel

Using MySQL JSON Columns with Laravel This is the source code behind the Laracasts Larabit: Using MySQL JSON Columns with Laravel, and features all of

Andrew Schmelyun 2 Dec 24, 2021
Store your Laravel application settings in an on-disk JSON file

Store your Laravel application settings in an on-disk JSON file. This package provides a simple SettingsRepository class that can be used to store you

Ryan Chandler 24 Nov 16, 2022
Laravel API wrapper to interact fluently with your Janus Media Server

Laravel API wrapper to interact fluently with your Janus Media Server. Core server interactions, as well as the video room plugin included.

Richard  Tippin 11 Aug 21, 2022
BigBlueButton Server API Library for Laravel

BigBlueButton Server API Library for Laravel Package that provides easily communicate between BigBlueButton server and laravel framework Requirements

Jignesh 124 Jan 6, 2023
Get estimated read time of an article. Similar to medium.com's "x min read". Multilingual including right-to-left written languages. Supports JSON, Array and String output.

Read Time Calculates the read time of an article. Output string e.g: x min read or 5 minutes read. Features Multilingual translations support. Static

Waqar Ahmed 8 Dec 9, 2022
PHP Simple Response, XML, JSON,... auto response with accept in request's header

simple-response Simple package to handle response properly in your API. This package does not include any dependency. Install Via Composer $ composer

Phuong Danh 3 Dec 8, 2021
Tool to convert from composer.yml to composer.json.

composer-yaml This project allows you to convert a composer.yml file into composer.json format. It will use those exact filenames of your current work

Igor 56 Sep 28, 2022
The list of all Algerian provinces and cities according to the official division in different formats: csv, xlsx, php, json, etc.

algeria-cities This repository contains the list of all the administrative provinces and cities in Algeria. The data is up-to-date according to the of

Ramtani Othmane 393 Jan 2, 2023
Generate Data Transfer Objects directly from JSON objects

Json 2 DTO Spatie's Data Transfer Object library is awesome, but typing out DTOs can quickly become a chore. Inspired by Json2Typescript style tools,

null 111 Jan 3, 2023
Iconify icon sets in JSON format

100+ open source icon sets. Icons are validated, cleaned up, optimised, ready to render as SVG

Iconify 255 Dec 29, 2022
A demo of how to use filament/forms to build a user-facing Form Builder which stores fields in JSON.

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Dan Harrin 41 Dec 24, 2022
This is a plugin written in the PHP programming language and running on the PocketMine platform that works stably on the API 3.25.0 platform. It helps to liven up your server with Tags!

General This is a plugin written in the PHP programming language and running on the PocketMine platform that works stably on the API 3.25.0 platform.

Thành Nhân 4 Oct 21, 2021
List of 77 languages for Laravel Framework 4, 5, 6, 7 and 8, Laravel Jetstream , Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova and Laravel Spark.

Laravel Lang In this repository, you can find the lang files for the Laravel Framework 4/5/6/7/8, Laravel Jetstream , Laravel Fortify, Laravel Cashier

Laravel Lang 6.9k Jan 2, 2023