Can the config repository contract include the typed value methods? #57276
Replies: 1 comment 1 reply
-
Context: Laravel Contracts Philosophy Laravel’s contracts (interfaces) are designed to describe core framework abstractions — the minimum methods necessary for interoperability and dependency inversion. So for example: \Illuminate\Contracts\Config\Repository defines the minimal surface area for a configuration repository — mainly get(), set(), has(), etc. The concrete \Illuminate\Config\Repository class extends this contract with convenience helpers (->string(), ->integer(), ->boolean(), etc.) that make life easier in app code. ⚙️ Why the Typed Accessors Aren’t in the Contract There are a few practical and design reasons: Backward Compatibility and Minimal Guarantees Contracts are promises of API stability. Even if Laravel itself only ships one implementation, there are many community or test double implementations out there (e.g., for testing, mocks, or alternative config stores). Contracts Should Stay Lean The philosophy is to keep contracts narrow and focused. The type helpers (bool(), string(), etc.) are quality-of-life utilities, not core config responsibilities. Type Conversion Is Convenience, Not Contractual Behavior The goal of a contract is to define behavior that’s essential for the system to function, not to enforce sugar methods. Conversions are more about ergonomics — they don't change how configuration is stored or retrieved fundamentally. DI and Flexibility By limiting the contract, Laravel ensures you can inject any configuration store that behaves like a key-value repository, without worrying about typed convenience helpers. You can still wrap or decorate the contract in your own typed-accessor layer if you want strict typing via DI. 🧩 If You Want to Use Those Helpers via DI You have a few practical options: Option 1: Type-hint the concrete implementation public function __construct(Repository $config) Yes, it’s more coupled — but if you’re okay depending on Laravel’s implementation, it’s perfectly fine. Option 2: Extend the contract in your own app Then bind Laravel’s Repository as your implementation in a service provider: $this->app->bind(TypedConfigRepository::class, \Illuminate\Config\Repository::class); This keeps your own code loosely coupled to your abstraction, while still leveraging Laravel’s typed accessors. 💭 Would a PR Be Welcome? Probably not in the main illuminate/contracts package, for the reasons above. That said, if your PR were to add docblock typing hints or helper traits rather than modify the interface itself, it might have a chance — but expanding contracts directly is usually declined. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I've always been curious why the
Config
/Repository
facade and implementation have the->bool()
,->string()
, etc. methods available to them to convert configuration values to an expected type, though those conversion methods do not exist on the\Illuminate\Contracts\Config\Repository
interface.As a DI enjoyer that limits my use of facades out of personal preference, I lean on injection via contracts heavily, including using the config contract repository. I always find myself missing those type conversion methods and fallback to injecting the
Repository
implementation. This feels a bit unnatural and somewhat defeats the purpose of loosely coupled DI injecting a concrete implementation.Is there a technical reason those type conversion methods do not exist on the repository contract interface? I'm a newer-ish lurker to the framework code, though have been working with Laravel for quite some time now. Grepping around, the config repository contract only has one implementation in the concrete config repository, so it seems like this could be possible.
Apologies if this has been asked before, just wanted to ask out of curiosity before sending out potential PR for this.
Beta Was this translation helpful? Give feedback.
All reactions