pedrosalpr/laravel-api-problem
Laravel API Problem brings RFC 7807/9457 problem details to your Laravel API, helping you return consistent, standards-compliant JSON error responses. Document, debug, and consume API errors more easily with structured problem payloads and simple helpers.
Architecture fit. RFC 9457 (Problem Details for HTTP APIs, which obsoletes RFC 7807) defines a machine-readable error contract — application/problem+json with type, title, status, detail, and instance members plus free-form extension members. This package maps Laravel's exception rendering pipeline onto that contract. Architecturally it is a presentation-layer concern only: no domain coupling, no persistence, no queueing, no service container gymnastics beyond a provider registration. That makes it a low-blast-radius addition that composes cleanly with Laravel's existing Handler::render/report hooks. Fit is high for public or partner-facing APIs where multiple clients (web SPA, mobile, third-party integrators) need a stable error contract; it is close to zero value for internal-only services or where an error envelope already exists.
Integration feasibility. The natural seams are the service provider, the exception handler, and config publishing. Realistic effort is one engineer for one to two days including tests, assuming the package hooks per-exception or via a config toggle. The critical feasibility question is whether it intercepts globally or opt-in — a global override changes every error response in the application and is effectively a breaking API change. Second critical question: does it normalize ValidationException (422) into a problem document with an errors extension member? In most Laravel APIs 4xx validation failures are the highest-volume error class, so coverage there determines whether the standard is actually uniform or merely cosmetic.
Technical risk.
detail, instance, and any debug/trace extension members must be gated on app.debug. A misconfiguration here leaks internals into production responses — highest-severity failure mode.application/problem+json and that member semantics match 9457 rather than the older 7807 phrasing.Key questions.
composer.json; is CI running against the versions we pin?Throwable.Accept negotiation, or always return problem+json?type URIs configurable per exception?title/detail localizable via Laravel's translator?Stack fit. Standard Laravel 9/10/11 + PHP 8.x JSON APIs. It should coexist with Sanctum, FormRequest validation, API Resources, and route middleware without conflict. The one thing to check early is interaction with any existing response wrapper or Response::macro — two competing error envelopes in one codebase is worse than either alone. Confirm behavior when the app is behind a gateway that inspects or rewrites Content-Type.
Migration path. Do not enable globally on day one.
Compatibility. Verify composer constraints against the pinned framework before committing. Check that the generated documents validate against our OpenAPI error schema, that client SDKs and any schema validators accept application/problem+json, and that monitoring/APM tooling parses the new body. Errors emitted outside the Laravel kernel — web server 502s, load balancer timeouts, queue worker failures — will never be conformant, so the published contract needs an explicit disclaimer or those paths need a gateway-level shim.
Sequencing.
Content-Type, and required members for every error path; an alert on non-conforming error responses.Maintenance. Near-zero runtime footprint — no migrations, no scheduled jobs, no external services. The carrying cost is dependency hygiene and the fork burden if upstream goes quiet. Assign an explicit owner and budget roughly one to two days per quarter for Laravel/PHP major bumps and mapping changes. Define an upstream health trigger now: if there is no release or issue response for six months, fork into an internal namespace rather than waiting for an upgrade to force the decision.
Support. Community-only, no commercial backing, small user base. Internal runbook must cover: how to disable in under five minutes (config flag or handler revert), how to add a new exception mapping, the error type URI taxonomy and who approves additions, and the rule for when an extension member is warranted versus when detail suffices. Escalation lands on the team that owns the API layer — there is no vendor to call.
Scaling. Serialization-only cost per error, negligible against request volume. Two things to watch: response payload size if detail or extension members get verbose during error storms (auth failures, rate limiting), and log amplification if every problem document is logged at error level. Sample or rate-limit 4xx logging.
Failure modes.
APP_DEBUG=false.Accept: application/json reject problem+json.Ramp-up. Low. Half a day for one engineer to read the source, one day to integrate with tests. Team-wide ramp is about the error taxonomy convention, not the package: agree on type URI patterns, when to add extension members, and what must never appear in detail. Document that once, and new contributors are productive immediately.
Recommendation. Adopt with conditions, or reimplement. As a standardization mechanism for a public or partner-facing Laravel API it is proportionate and cheap; as a critical-path dependency it is not defensible at this maturity level. Pin the version, wrap it behind an internal seam, gate it per route group, version the API before flipping defaults, and treat the source as a reference implementation we are prepared to own.
How can I help you explore Laravel packages today?