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

Service Proxy Laravel Package

openclassrooms/service-proxy

A lightweight Laravel/PHP service proxy from OpenClassrooms that sits between your application and its services, centralizing calls behind a clean, testable interface so business logic stays decoupled from transport details. Useful for wrapping external APIs or internal service layers.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install it as a plain library. composer require openclassrooms/service-proxy. There is no indication of a Laravel service provider with auto-discovery; check vendor/openclassrooms/service-proxy/composer.json for extra.laravel.providers and register manually in config/app.php (or bootstrap/providers.php on Laravel 11+) if one exists.
  • Pin the version deliberately. You are now on v11.0.0, a major bump whose only stated change is a chore: migrate phpdoc parser to v2. That wording is the tell: the library generates proxy code by parsing docblocks, so the parser upgrade is a real behavioural change even though the package's own API may be untouched. Pin "openclassrooms/service-proxy": "11.0.*" (or an exact version) and read the diff between v10.0.1 and v11.0.0 before adopting.
  • Read src/ first, not the README. With zero stars and few dependents, documentation is thin. The authoritative contract is the public classes in src/: the base ServiceProxy/AbstractServiceProxy, the generator/factory that turns a class-string into a proxy, and any Contracts/ folder. The docblock reader lives in the generator — that is the code the v11 change touched, so start there.
  • Confirm the proxy style before designing around it — v11 narrows this down. The phpdoc-parser dependency strongly implies generated proxies built from the wrapped class's docblocks (type info for @param/@return/@method/@property), not a hand-written decorator. Check whether the constructor takes an instance (decorator) or a class-string/closure (generated lazy proxy); the parser migration only matters in the generated case.
  • First use case: isolate a flaky third-party client. Wrap your SDK client (Stripe, an internal HTTP service, a legacy SOAP client) so application code depends on your own interface, not the vendor's. Lowest-risk trial, easiest to roll back.
// app/Services/Billing/StripeGateway.php  (implements BillingGateway)
final class StripeGateway implements BillingGateway { /* vendor calls */ }

// app/Services/Billing/BillingGatewayProxy.php
class BillingGatewayProxy extends ServiceProxy implements BillingGateway
{
    public function charge(int $cents): Receipt
    {
        return $this->proxy()->charge($cents); // delegate + intercept
    }
}

Bind it in a service provider:

$this->app->bind(BillingGateway::class, fn ($app) =>
    new BillingGatewayProxy($app->make(StripeGateway::class))
);

Implementation Patterns

  • Decorator-per-concern. The most durable use of the proxy layer is stacking cross-cutting behaviour around one real service: retry/backoff, circuit breaking, timing/metrics, structured logging, response caching. One concern per proxy class, composed in the container so ordering is explicit and testable.
  • Lazy service resolution. If the class is a generated virtual proxy (class-string constructor), use it to defer expensive construction — a client that opens a socket, a service that reads config — until the first method call. This is what justifies the package over a plain wrapper.
  • Golden-file the generated proxies. Because generation is docblock-driven, snapshot the generated proxy for each wrapped service into your test suite (or a CI artefact) and diff it on upgrade. On v11 that snapshot is the fastest way to see whether phpdoc-parser v2 changed a signature, a type, or a docblock it now rejects.
  • Test doubles without mocking frameworks. The proxy sits between your code and the real service, so substitute a hand-written fake implementing the same interface in feature tests — the proxy's interception behaviour stays under test while the network disappears.
  • Adapter over multiple backends. One interface (Mailer, Search, Storage), several concrete implementations, a proxy that selects or falls back between them. Good for migrating from a legacy provider behind a feature flag.
  • Integrate at the container boundary, not deep in domain code. Never new Proxy(...) inside a domain object. Bind once in a service provider so it is swappable and config:cache works.
  • Test the proxy itself in isolation. Assert delegation (inner service got the right arguments) and interception (retry fired, metrics recorded). Cheap unit tests that catch most regressions on upgrade — and they are how you'll validate v11.
  • Pair with Laravel's HTTP fake / queue fake for the inner layer. Let the proxy do retry/logging, let the framework fake the transport; deterministic tests without mocking the proxy away.

Gotchas and Tips

  • v11 is a parser upgrade wearing a chore: label. A major version bump for a dependency migration means consumers must treat it as potentially breaking. Concrete risks: docblocks that were previously tolerated may now throw or be ignored; exotic types (generics, conditional types, array{...} shapes, @method/@property annotations) may render differently in generated signatures. Regenerate every proxy and diff before shipping.
  • Beware the shared phpstan/phpdoc-parser constraint. If v11 pulls phpstan/phpdoc-parser ^2 (the likely v1→v2 migration), it can conflict with anything in your app still requiring ^1 — Larastan/PHPStan at older majors, Psalm plugins, other codegen tools. Resolve with composer why phpstan/phpdoc-parser before blaming the library, and be ready to bump your static-analysis stack in the same PR.
  • Proxying final classes or methods is a hard blocker for generated proxies. Code generation cannot subclass final, override final methods, or proxy private methods. Verify wrapped services are non-final, or use decorator mode.
  • Return types and typed properties survive — sometimes. Generated proxies can lose self/static return types, by-ref parameters, variadics, and union types. Smoke-test every proxied method returning static or taking &$ref — especially after a major, since the parser produces the type text.
  • Stack traces get confusing. Exceptions show a generated proxy class (e.g. ProxyManagerGeneratedProxy\...) as the failing frame. Unwrap with getWrappedValue() / getWrappedInstance() if exposed, otherwise filter debug_backtrace().
  • config:cache and generated proxies don't always mix. If proxies are generated on first use and cached to disk, warm them during build/deploy, add the cache directory to .gitignore, and clear it (php artisan optimize:clear plus the library's cache path) after every upgrade — v11 in particular. Stale generated code from v10 is the most likely cause of "it worked locally but breaks in CI".
  • Circular dependencies. Proxying a service that proxies back to you can deadlock or infinitely recurse. Prefer leaf services (HTTP clients, mailers) over hubs (repositories depending on many things).
  • Serialization. Proxied objects generally do not serialize cleanly (closures, generated classes). Don't put a proxy instance on a queued job — inject it, or pass the resolved result / service name.
  • Interception order is your responsibility. No guaranteed ordering for stacked decorators; compose explicitly (retry outside logging, metrics outside retry) and assert the sequence in a test.
  • Extension points. Look for an interceptor/handler registry or before/after method hooks in src/ — that is where auth headers and correlation IDs belong, rather than copy-pasted delegation methods.
  • Keep the dependency contained. Zero stars, few dependents, and a major bump for a "chore" all argue for keeping the proxy behind your own interface so swapping in a hand-rolled decorator is a one-file change. Pin the version, read the changelog (v10.0.1...v11.0.0) before upgrading, and upgrade on your schedule rather than via composer update.
  • Prefer it only where indirection pays. One simple wrapper is better served by a plain decorator class. Adopt this package when you want consistent lazy resolution, interception, or generated proxies across many services — not for one.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect