Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Json Rpc Bundle Laravel Package

neofusion/json-rpc-bundle

NeoFusion JSON-RPC Bundle provides a JSON-RPC 2.0 server and client for Symfony applications, letting you expose services as remote procedures and call them from other apps. It handles request parsing, method resolution, error responses, and batch calls, keeping your API layer clean and spec-complia...

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package — there is no service provider, no config/json_rpc.php, and no facade. As a Laravel developer you have two realistic entry points: (a) use it inside a Symfony app that your team also owns, or (b) read it as a reference implementation and port the ~300 lines of dispatch logic into a Laravel controller + container binding. Given it is archived (last release 2019-05-28) and has essentially zero dependents, treat it as a spec/implementation reference first and a dependency second.

Minimal steps if you are actually installing it in Symfony:

  1. Pin it: composer require neofusion/json-rpc-bundle:^1.0 (the archived release will not tolerate loose constraints against modern Symfony; expect to downgrade Symfony or fork).
  2. Register the bundle in config/bundles.php (NeoFusion\JsonRpcBundle\NeoFusionJsonRpcBundle::class => ['all' => true]).
  3. Publish/define the endpoint in the bundle config — read DependencyInjection/Configuration.php for the exact root key and endpoint option rather than trusting the README, which is thin.
  4. Tag one service as a JSON-RPC method provider (json_rpc.method tag with a method attribute naming the exposed namespace, e.g. math).
  5. POST a JSON-RPC 2.0 envelope to the endpoint:
{"jsonrpc":"2.0","method":"math.add","params":{"a":1,"b":2},"id":1}

Where to look first: Controller/ (the HTTP entrypoint and envelope validation), Service/ (the dispatcher that resolves method → tagged service → public method), and DependencyInjection/ (tag name, config schema). The README is short; the dispatcher is the actual contract.

First use case: expose a handful of internal application services (pricing, inventory lookups, reporting) over an internal-only RPC endpoint that a separate frontend or mobile BFF calls, instead of hand-rolling one controller per operation.

Implementation Patterns

Tag-per-class, method-per-public-function. The idiomatic pattern is a small class per domain whose public methods are the RPC methods. The tag's method attribute is the namespace prefix; the public method name is the suffix. Keep these classes thin — they should delegate to real domain services, not contain business logic, because everything public is effectively API surface.

// config/services.yaml
App\Rpc\MathRpc:
    tags:
        - { name: json_rpc.method, method: 'math' }

Named parameters are the contract. Params arrive as an associative array and are bound by name. Always call with named params ("params":{"a":1,"b":2}), never positional arrays, because the dispatcher maps them to method arguments — positional payloads break the moment you reorder a signature. Document the parameter shape per method; there is no schema validation in the bundle.

One endpoint, many methods. Don't create multiple routes for multiple operations. The whole point is a single /json-rpc endpoint with method-based routing — that is what makes batch requests meaningful. A batch is just a JSON array of envelopes; use it to coalesce dashboard/mobile startup calls into one round-trip.

Auth and rate limiting via Symfony listeners, not the bundle. There is no built-in authentication. Mount the endpoint behind your existing firewall, and use a kernel.request listener or a security voter to inspect the method name and enforce per-method authorization. This is the cleanest extension point the bundle leaves you.

Error mapping through exceptions. Throw a domain exception from a tagged method and let a listener (or a small wrapper) translate it into a JSON-RPC error object with a stable code and message. Reserve the transport-level codes (-32700 parse, -32600 invalid request, -32601 method not found, -32602 invalid params) for the bundle and use a private -32000..-32099 range for application errors. Clients will branch on code, so define the codes once in a shared enum.

Laravel port pattern (if you are not using Symfony). The bundle's value to a Laravel team is the shape, not the code. Bind a dispatcher singleton, key a registry off a config array ('methods' => ['math.add' => [MathRpc::class, 'add']]), validate the envelope (version, method string, params array-or-object, id scalar-or-absent for notifications), and return a single controller response that handles both single and batch payloads. That is the entire bundle, and it is ~150 lines you control.

Testing. Hit the endpoint with Symfony's KernelBrowser (or Laravel's $this->postJson) and assert on the jsonrpc, result/error, and id envelope fields — never on raw response bodies. Add one test per error code; the dispatcher's envelope handling is the part most likely to drift if you fork.

Gotchas and Tips

  • Archived and unmaintained. No PHP 8.1+ guarantees, no Symfony 6 compatibility promise, no security patches. Do not ship it on a new project without forking and pinning. Audit composer.lock for transitive Symfony constraints before adopting.
  • No Laravel integration at all. There is no service provider, facade, or config publish. Attempting to composer require it into Laravel will pull Symfony HTTP/DI components and give you nothing you can call. Port it or wrap it behind an HTTP boundary.
  • All public methods are exposed. The tag does not restrict which methods are callable — every public function on a tagged class becomes an RPC method. Keep RPC classes free of helpers, __construct dependencies aside, and prefer a facade class that explicitly forwards to a few methods over a fat service.
  • No parameter validation or coercion. Types are whatever PHP's loose binding gives you. Validate and cast inside the method or in a dispatcher wrapper; clients will send strings for integers and null for optional fields.
  • Notifications return nothing. A request without an id is a notification and must produce an empty response body (HTTP 204 or empty 200 depending on your setup). Clients that always expect a JSON body will choke — document this.
  • Batch semantics are all-or-nothing at the transport layer but per-item at the result layer. A batch of mixed success/failure must return an array of result/error objects, not a single error. Test this explicitly; it is the most commonly broken part of hand-rolled JSON-RPC.
  • Route/config discovery. The endpoint path lives in the bundle's DI Configuration.php, not the README. Grep for endpoint in DependencyInjection/ before assuming a default.
  • Debugging. Log the raw request body and the resolved method name in a kernel.request/kernel.response listener — the bundle's own logging is sparse, and a malformed envelope gives a generic -32600 with no hint. Symfony profiler will show the controller but not the dispatch decision.
  • Extension points worth using: the method tag attribute (namespace), the security firewall (auth), kernel.exception (error mapping), and the dispatcher service if you fork (method registry). Everything else is hardcoded and not worth fighting.
  • Verdict for day-to-day leverage: low as a dependency, moderate as a blueprint. If you need JSON-RPC 2.0 in Laravel, copy the envelope/dispatch logic and write your own controller; if you are on Symfony and already own the stack, budget a day to fork and pin, because the upstream is frozen.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle