Open boesing opened 1 year ago
Could we wire up a service in the config provider here so that components that ship plugin managers can use that service to perform runtime validation in the plugin manager factory?
Say a service something like this:
namespace Laminas\ServiceManager;
/** @psalm-import-type ServiceManagerConfiguration from ServiceManager */
final readonly class ConfigValidationService
{
public function __construct(private ValidatorInterface $validator, private bool $enabled)
{
}
/** @psalm-assert ServiceManagerConfiguration $config */
public function validate(array $config): void
{
if (! $this->enabled) {
return;
}
$this->validator->assertValidConfig($config);
}
}
… where $this->enabled
is equivalent to $config['debug']
and in a plugin manager factory, something like:
final class PluginManagerFactory
{
public function __invoke(ContainerInterface $container): ValidatorPluginManager
{
$config = $container->get('config');
$services = $config['validators'] ?? [];
$validator = $container->get(ValidatorInterface::class);
$validator->validate($services);
return new PluginManager($services);
}
}
I have not yet a clue on how to effectively use it, as I would actually prefer to only validate prior configuration caching so that not every request has to validate the same valid/invalid config over and over again.
Yeah. I'd argue that validating configuration is a job for whatever build tool you use, not a runtime check.
As a developer, if I'm changing the config it's going to be obvious pretty quickly if an alias
I've introduced does not resolve. If it's set to something different in production that's a problem. But does throwing an exception when the configuration is first loaded - as opposed to when the invalid dependency is first used - really make my life any easier? The borked config should never have got so far.
Maybe these could be made into reusable smoke tests instead?
Description
Starting with v4.0.0, the
ServiceManager
itself will not validate anymore as it provides psalm array-shape type for configuration values.As per existing projects, the
ServiceManager
is usually configured somehow like these examples:The first example does use deprecated
Config
instance which just verified that pre-defined array keys are provided. The second example does not verify anything and assumes the config to be correct.Both cases do either need a psalm-baseline entry or a
psalm-suppress
once migrated to SM v4.0.0 (at least the second example already needs that as it uses theServiceManager#__construct
which is already properly typed.Closes #131
So every pluginmanager providing component (such as
laminas-cache
,laminas-form
, etc. - I've listed some more in the TSC meeting) would also need either a baseline entry or suppression due to the fact that there is no current way to verify that configuration matches expectations.To avoid that, we could in fact use a runtime configuration validator which is provided by this PR.
I have not yet a clue on how to effectively use it, as I would actually prefer to only validate prior configuration caching so that not every request has to validate the same valid/invalid config over and over again. I've created this PR as a draft so that we can find a way of how to effectively use such a validator. In mezzio projects, having this as some kind of
PostProcessor
forconfig-aggregator
would work but that won't work for i.e. laminas-formWould love to get some help here.