API Platform version(s) affected: 3.0
Description
I recently tried upgrading to api-platform 3.0 and none of my entities were shown in the open-api documentation and got the message "No operations defined in spec!"
I later found that tbbc/money-bundle was responsible and when removing "tbbc/money-bundle": "^5.0" from composer.json, all was good.
How to reproduce
Create a minimum ApiPlatform installation and execute composer require tbbc/money-bundle.
Note that I haven't tested it using a dockers installation but only a composer install.
Possible Solution
ApiPlatformExtension::getBundlesResourcesPaths() appears to return bundle paths (i.e. not application paths) which might be an ApiResource.
ApiPlatformExtension::getResourcesToWatch() appears to return both bundle paths and application paths which might be an ApiResource.
If ApiPlatformExtension::getBundlesResourcesPaths() returns any paths, then ApiPlatformExtension::getResourcesToWatch() incorrectly does not return any application paths per below.
final class ApiPlatformExtension extends Extension implements PrependExtensionInterface
{
...
private function getResourcesToWatch(ContainerBuilder $container, array $config): array
{
$paths = array_unique(array_merge($this->getBundlesResourcesPaths($container, $config), $config['mapping']['paths']));
// Default paths
if (!$paths) {
$projectDir = $container->getParameter('kernel.project_dir');
foreach (["$projectDir/config/api_platform", "$projectDir/src/ApiResource", "$projectDir/src/Document", "$projectDir/src/Entity"] as $dir) {
if (is_dir($dir)) {
$paths[] = $dir;
}
}
}
...
}
...
}
To fix the problem, ApiPlatformExtension::getResourcesToWatch() must be changed as shown:
final class ApiPlatformExtension extends Extension implements PrependExtensionInterface
{
...
private function getResourcesToWatch(ContainerBuilder $container, array $config): array
{
$paths = array_unique(array_merge($this->getBundlesResourcesPaths($container, $config), $config['mapping']['paths']));
// Default paths
//if (!$paths) {
$projectDir = $container->getParameter('kernel.project_dir');
foreach (["$projectDir/config/api_platform", "$projectDir/src/ApiResource", "$projectDir/src/Document", "$projectDir/src/Entity"] as $dir) {
if (is_dir($dir)) {
$paths[] = $dir;
}
}
//}
...
}
...
}
Additional Context
Tring to determine the cause, I found that AttributesResourceNameCollectionFactory::__construct() was being passed [/var/www/facdocs/api2/vendor/tbbc/money-bundle/src/Entity] when having money installed and [/var/www/facdocs/api2/src/ApiResource, /var/www/facdocs/api2/src/Entity]when it wasn't.
<?php
namespace ApiPlatform\Metadata\Resource\Factory;
final class AttributesResourceNameCollectionFactory implements ResourceNameCollectionFactoryInterface
{
public function __construct(private readonly array $paths, private readonly ?ResourceNameCollectionFactoryInterface $decorated = null)
{
w/o money, $path is [/var/www/facdocs/api2/src/ApiResource, /var/www/facdocs/api2/src/Entity]
w/ money, $path is [/var/www/facdocs/api2/vendor/tbbc/money-bundle/src/Entity]
}
}
Next I looked App_KernelDevDebugContainer which is sourcing AttributesResourceNameCollectionFactory::__construct().

I then looked at the generated App_KernelDevDebugContainer under the two scenarios and found the following differences (full files are at the bottom of this post).
michael@michael-HP-EliteBook-830-G5:/var/www/facdocs/api2$ diff App_KernelDevDebugContainer_with_money.php App_KernelDevDebugContainer_without_money.php
3c3
< namespace Container6vIlWzN;
---
> namespace ContainerIRTbYPQ;
70,77d69
< 'tbbc_money.formatter.money_formatter' => 'getTbbcMoney_Formatter_MoneyFormatterService',
< 'tbbc_money.money_manager' => 'getTbbcMoney_MoneyManagerService',
< 'tbbc_money.pair.csv_storage' => 'getTbbcMoney_Pair_CsvStorageService',
< 'tbbc_money.pair_manager' => 'getTbbcMoney_PairManagerService',
< 'tbbc_money.ratio_provider.google' => 'getTbbcMoney_RatioProvider_GoogleService',
< 'tbbc_money.ratio_provider.yahoo_finance' => 'getTbbcMoney_RatioProvider_YahooFinanceService',
< 'tbbc_money.twig.currency' => 'getTbbcMoney_Twig_CurrencyService',
< 'tbbc_money.twig.money' => 'getTbbcMoney_Twig_MoneyService',
530a523
> $b->addDriver(($this->privates['doctrine.orm.default_attribute_metadata_driver'] ?? ($this->privates['doctrine.orm.default_attribute_metadata_driver'] = new \Doctrine\ORM\Mapping\Driver\AttributeDriver([0 => (\dirname(__DIR__, 4).'/src/Entity')]))), 'App\\Entity');
532,537c525
< $c = ($this->privates['doctrine.orm.default_attribute_metadata_driver'] ?? ($this->privates['doctrine.orm.default_attribute_metadata_driver'] = new \Doctrine\ORM\Mapping\Driver\AttributeDriver([0 => (\dirname(__DIR__, 4).'/src/Entity'), 1 => (\dirname(__DIR__, 4).'/vendor/tbbc/money-bundle/src/Entity')])));
<
< $b->addDriver($c, 'App\\Entity');
< $b->addDriver($c, 'Tbbc\\MoneyBundle\\Entity');
<
< $a->setEntityNamespaces(['App' => 'App\\Entity', 'TbbcMoneyBundle' => 'Tbbc\\MoneyBundle\\Entity']);
---
> $a->setEntityNamespaces(['App' => 'App\\Entity']);
1488d1475
< $instance->addXmlMappings([0 => (\dirname(__DIR__, 4).'/vendor/symfony/form/Resources/config/validation.xml')]);
1623d1609
< 'TbbcMoneyBundle' => 'Tbbc\\MoneyBundle\\TbbcMoneyBundle',
1658,1661d1643
< 'TbbcMoneyBundle' => [
< 'path' => (\dirname(__DIR__, 4).'/vendor/tbbc/money-bundle/src'),
< 'namespace' => 'Tbbc\\MoneyBundle',
< ],
1670,1674d1651
< 'Symfony\\Component\\Form\\Event\\PreSubmitEvent' => 'form.pre_submit',
< 'Symfony\\Component\\Form\\Event\\SubmitEvent' => 'form.submit',
< 'Symfony\\Component\\Form\\Event\\PostSubmitEvent' => 'form.post_submit',
< 'Symfony\\Component\\Form\\Event\\PreSetDataEvent' => 'form.pre_set_data',
< 'Symfony\\Component\\Form\\Event\\PostSetDataEvent' => 'form.post_set_data',
1717,1718d1693
< 'form.type_extension.csrf.enabled' => true,
< 'form.type_extension.csrf.field_name' => '_token',
1896c1871,1872
< 0 => (\dirname(__DIR__, 4).'/vendor/tbbc/money-bundle/src/Entity'),
---
> 0 => (\dirname(__DIR__, 4).'/src/ApiResource'),
> 1 => (\dirname(__DIR__, 4).'/src/Entity'),
1938,1964d1913
< 'tbbc_money.pair_manager.class' => 'Tbbc\\MoneyBundle\\Pair\\PairManager',
< 'tbbc_money.pair_manager_interface.class' => 'Tbbc\\MoneyBundle\\Pair\\PairManagerInterface',
< 'tbbc_money.money_manager.class' => 'Tbbc\\MoneyBundle\\Money\\MoneyManager',
< 'tbbc_money.pair_history_manager.class' => 'Tbbc\\MoneyBundle\\PairHistory\\PairHistoryManager',
< 'tbbc_money.pair.csv_storage.class' => 'Tbbc\\MoneyBundle\\Pair\\Storage\\CsvStorage',
< 'tbbc_money.pair_manager.ratio_file_name' => (\dirname(__DIR__, 4).'/../data/tbbc_money/ratio_file_name.csv'),
< 'tbbc_money.ratio_provider.yahoo_finance.class' => 'Tbbc\\MoneyBundle\\Pair\\RatioProvider\\YahooFinanceRatioProvider',
< 'tbbc_money.ratio_provider.google.class' => 'Tbbc\\MoneyBundle\\Pair\\RatioProvider\\GoogleRatioProvider',
< 'tbbc_money.ratio_provider.ecb.class' => 'Tbbc\\MoneyBundle\\Pair\\RatioProvider\\ECBRatioProvider',
< 'tbbc_money.formatter.money_formatter.class' => 'Tbbc\\MoneyBundle\\Formatter\\MoneyFormatter',
< 'tbbc_money.command.ratio_fetch.class' => 'Tbbc\\MoneyBundle\\Command\\RatioFetchCommand',
< 'tbbc_money.command.ratio_list.class' => 'Tbbc\\MoneyBundle\\Command\\RatioListCommand',
< 'tbbc_money.command.ratio_save.class' => 'Tbbc\\MoneyBundle\\Command\\RatioSaveCommand',
< 'tbbc_money.form_type.money.class' => 'Tbbc\\MoneyBundle\\Form\\Type\\MoneyType',
< 'tbbc_money.form_type.currency.class' => 'Tbbc\\MoneyBundle\\Form\\Type\\CurrencyType',
< 'tbbc_money.form_type.simple_money.class' => 'Tbbc\\MoneyBundle\\Form\\Type\\SimpleMoneyType',
< 'tbbc_money.twig.money.class' => 'Tbbc\\MoneyBundle\\Twig\\Extension\\MoneyExtension',
< 'tbbc_money.twig.currency.class' => 'Tbbc\\MoneyBundle\\Twig\\Extension\\CurrencyExtension',
< 'tbbc_money.currencies' => [
< 0 => 'USD',
< 1 => 'EUR',
< ],
< 'tbbc_money.reference_currency' => 'EUR',
< 'tbbc_money.decimals' => 2,
< 'tbbc_money.enable_pair_history' => false,
< 'tbbc_money.ratio_provider' => 'tbbc_money.ratio_provider.ecb',
< 'tbbc_money.pair.storage' => 'csv',
michael@michael-HP-EliteBook-830-G5:/var/www/facdocs/api2$
Not positive but looks like this script is the culprit:
namespace Container6vIlWzN;
class App_KernelDevDebugContainer extends Container
{
...
protected function getDefaultParameters(): array
{
return [
...
// with money bundle.
'api_platform.resource_class_directories' => [
0 => (\dirname(__DIR__, 4).'/vendor/tbbc/money-bundle/src/Entity'),
],
// instead of without money bundle installed.
'api_platform.resource_class_directories' => [
0 => (\dirname(__DIR__, 4).'/src/ApiResource'),
1 => (\dirname(__DIR__, 4).'/src/Entity'),
],
...
];
}
...
}
Tried a little to determine how Symfony creates this file but way on uncharted territory now.
Is this an api-platform issue or a tbbc/money-bundle issue? If an api-platform issue, are you able to fix? If a tbbc/money-bundle issue, any recommendations what I should tell them so they can fix it on their side?
Thanks in advance for a response, and more so thanks for building ApiPlatform 3.0!
Reference Only Information - Full App_KernelDevDebugContainer of both scenarios
Turns out it is too long and exceeds 65536 characters. If helpful, I can send it via different means,.
API Platform version(s) affected: 3.0
Description
I recently tried upgrading to api-platform 3.0 and none of my entities were shown in the open-api documentation and got the message "No operations defined in spec!"
I later found that tbbc/money-bundle was responsible and when removing
"tbbc/money-bundle": "^5.0"from composer.json, all was good.How to reproduce
Create a minimum ApiPlatform installation and execute
composer require tbbc/money-bundle.Note that I haven't tested it using a dockers installation but only a composer install.
Possible Solution
ApiPlatformExtension::getBundlesResourcesPaths() appears to return bundle paths (i.e. not application paths) which might be an ApiResource.
ApiPlatformExtension::getResourcesToWatch() appears to return both bundle paths and application paths which might be an ApiResource.
If ApiPlatformExtension::getBundlesResourcesPaths() returns any paths, then ApiPlatformExtension::getResourcesToWatch() incorrectly does not return any application paths per below.
To fix the problem, ApiPlatformExtension::getResourcesToWatch() must be changed as shown:
Additional Context
Tring to determine the cause, I found that
AttributesResourceNameCollectionFactory::__construct()was being passed[/var/www/facdocs/api2/vendor/tbbc/money-bundle/src/Entity]when having money installed and[/var/www/facdocs/api2/src/ApiResource, /var/www/facdocs/api2/src/Entity]when it wasn't.Next I looked
App_KernelDevDebugContainerwhich is sourcingAttributesResourceNameCollectionFactory::__construct().I then looked at the generated App_KernelDevDebugContainer under the two scenarios and found the following differences (full files are at the bottom of this post).
Not positive but looks like this script is the culprit:
Tried a little to determine how Symfony creates this file but way on uncharted territory now.
Is this an api-platform issue or a tbbc/money-bundle issue? If an api-platform issue, are you able to fix? If a tbbc/money-bundle issue, any recommendations what I should tell them so they can fix it on their side?
Thanks in advance for a response, and more so thanks for building ApiPlatform 3.0!
Reference Only Information - Full App_KernelDevDebugContainer of both scenarios
Turns out it is too long and exceeds 65536 characters. If helpful, I can send it via different means,.