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

olegkunitsyn/json-rpc-bundle

A Symfony bundle for building JSON-RPC 2.0 services, with request and response handling, method routing, structured error objects, and integration with the HTTP kernel and service container. Useful for exposing PHP application APIs to remote clients.

View on GitHub
Deep Wiki
Context7

Getting Started

The 7.0.1 release is a patch on the 7.x line, but the headline features — batches, DTOs, and response normalization — change how you should structure API integration code, so treat 7.x as the baseline for any new work (see Gotchas for upgrading from 6.x).

Install and publish configuration first:

composer require <vendor>/<package>:^7.0
php artisan vendor:publish --tag="<package>-config"   # publish config + any stubs/make commands

Where to look first, in order:

  1. UPGRADE.md and the 7.0.0 changelog entry — 7.0.1 fixes will not cover 6→7 renames.
  2. The published config file — base URL, timeout, retry, and the normalization/toggle keys live here; most "why doesn't it work" questions are answered in this file.
  3. The DTO contract or base class (often make:data-style generator) — this is the extension point you will touch daily.
  4. The batch API surface — look for a pool/batch/collect entry point on the client or a dedicated builder class.

First use case to prove the stack end-to-end: one endpoint, one DTO, one normalization path.

// 1. A read-only DTO per endpoint
final class OrderData extends Data   // or the package's DTO base class
{
    public function __construct(
        public readonly int $id,
        public readonly string $status,
        public readonly CarbonImmutable $createdAt,
    ) {}
}

// 2. A single call that returns the DTO, not an array
$order = Api::orders()->show($id)->dto(OrderData::class);

Once that round-trips cleanly (including a 404 and a 500), add a batch of 3–5 ids inside a queued job. If both paths work with the same DTO and the same normalizer, your integration is correctly wired.

Implementation Patterns

One DTO per response shape, not per endpoint. Share DTOs between the single-fetch and batch paths so that show() and a batched fetch of the same resource cannot drift apart. Keep DTOs readonly, give them a fromArray/from hydration entry point, and add toArray() so results can be cached, logged, or asserted in tests without touching the raw response.

Normalize once, at the boundary. Let the package's normalization layer produce the envelope (data / meta / errors) and convert it to a DTO immediately. Controllers and jobs should never see a raw response object. If you find yourself writing if (isset($json['data']['items'])) in a controller, that mapping belongs in the DTO or a custom normalizer.

Batches belong in jobs with chunking. Group batched calls by endpoint and by timeout budget, chunk to whatever the upstream provider rate-limits at, and return keyed results so partial failures can be attributed:

$results = Api::orders()->batch($ids, chunk: 50);   // keyed by id

$ok     = $results->successful();   // id => OrderData
$failed = $results->failed();       // id => ErrorData

Persist successes, then re-queue or dead-letter the failed subset — do not retry the whole batch. Use idempotency keys for any batched write (POST/PATCH) so a retry after a partial timeout doesn't duplicate records.

Integration points worth standardizing on day one:

  • Bind the client behind an interface in a service provider, and inject it — never new the client in a controller or a model.
  • One config/<package>.php per environment: base URL, timeout, retry/backoff, and concurrency for batches. Keep credentials in .env only.
  • Convert transport + normalization failures into a single application exception, so callers catch one type.
  • Add an artisan smoke command (api:ping) that hits a cheap endpoint and dumps the normalized payload; useful in CI and after deploys.
  • Assert DTOs, not raw arrays, in tests. Use the package's fake/recording facility (or Http::fake()) and keep one or two recorded fixtures checked in — normalization regressions show up as DTO diffs, which are easy to review.

Gotchas and Tips

  • 6.x → 7.x is where the breakage is. 7.0.1 is a patch, but the 7.0.0 line introduced DTO and normalization contracts; config keys, method signatures, and return types may have changed. Upgrade on a branch, run the test suite against recorded fixtures, and grep for direct array access into responses — those are the call sites that break.
  • Nested and coerced DTO fields are the usual failure point. Numeric strings from JSON, null for optional relations, snake_case vs camelCase, and date strings all need explicit handling in the hydration method. Prefer explicit casts (CarbonImmutable::parse, backed enums) over mixed — the whole value of DTOs is that a bad payload fails loudly at the boundary.
  • Partial batch failure is not an exception. Batch APIs typically return a mixed result set; if you let the first error throw, you silently discard the successes and re-request them next run. Inspect successful() / failed() explicitly.
  • Don't normalize twice. If you pass an already-normalized payload back through the normalizer (common when caching responses and replaying them), you get double-wrapped envelopes. Cache the DTO's toArray(), not the raw response, or bypass normalization on replay.
  • Non-JSON responses slip past DTO hydration. 204 No Content, HTML error pages from a proxy, and gateway timeouts are not JSON and will produce confusing hydration errors. Guard for empty bodies and surface the status code and a truncated body in the exception message.
  • Timeouts stack. The client timeout, batch concurrency window, and the queue worker's --timeout interact; a batch that takes 90s will be killed by a 60s worker. Size chunks against the worker timeout, not the client's.
  • 429s turn into retry storms. Exponential backoff plus per-host concurrency limits; make sure retries are disabled or capped for non-idempotent writes.
  • Testing fakes skip normalization by default. If the fake returns DTOs directly, your normalizer is untested. Keep at least one test that exercises the real normalization path against a stored fixture.
  • Extension points to reach for before forking: a custom normalizer registered in config or the container, a custom DTO resolver/hydrator for non-standard payload shapes, and client middleware for logging/correlation IDs. Add per-service clients (one config entry each) rather than branching inside a single client.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core