When creating a custom resource whenever I load something from storage (like a node) I get a failure at the endpoint:
Uncaught PHP Exception LogicException: "The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\Core\Cache\CacheableResponse." at /var/www/drupal-8.2.x-dev/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php line 159"
My custom ServiceDefinition is quite simple and all is well until it hits the EarlyRenderingControllerWrapperSubscriber. It seems that some toUrl function gets called touching the cache outside of context. I have this with 8.0.5, 8.1.0-beta2 and 8.2-dev of drupal.
My resource
namespace Drupal\MyModule\Plugin\ServiceDefinition;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Flood\FloodInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\services\ServiceDefinitionBase;
use Drupal\user\UserAuthInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\Routing\Route;
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\SerializerInterface;
/**
* @ServiceDefinition(
* id = "node_extended",
* methods = {
* "GET"
* },
* title = @Translation("Extended Node Resource"),
* description = @Translation("."),
* translatable = false,
* category = @Translation("Node"),
* path = "node_extended"
* )
*
*/
class NodeExtended extends ServiceDefinitionBase implements ContainerFactoryPluginInterface {
/**
* Constructs a HTTP basic authentication provider object.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\user\UserAuthInterface $user_auth
* The user authentication service.
* @param \Drupal\Core\Flood\FloodInterface $flood
* The flood service.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager service.
* @param Session $session
*/
public function __construct($configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config_factory, UserAuthInterface $user_auth, FloodInterface $flood, EntityManagerInterface $entity_manager, Session $session) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->configFactory = $config_factory;
$this->userAuth = $user_auth;
$this->flood = $flood;
$this->entityManager = $entity_manager;
$this->session = $session;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('config.factory'),
$container->get('user.auth'),
$container->get('flood'),
$container->get('entity.manager'),
$container->get('session')
);
}
/**
* {@inheritdoc}
*/
public function processRoute(Route $route) {
$route->setRequirement('_user_is_logged_in', 'TRUE');
}
/**
* {@inheritdoc}
*/
<strong> public function processRequest(Request $request, RouteMatchInterface $route_match, SerializerInterface $serializer) {
return $this->entityManager->getStorage('node')->load(1);
}</strong>
}