Score:0

Set cacheability on a custom route returning XML

in flag

I'm working on fixing a custom module that returns XML from a certain route. Essentially what is described in the answers of this question.

Currently this route isn't being cached. I've tried to switch to using CacheableResponse and setting cache tags but received the error "The controller result claims to be providing relevant cache metadata, but leaked metadata was detected"

At this point I feel a bit lost. How can I adjust caching for this route so it's cached until the returned XML changes?

Here's my current response:

/**
 * Class CustomEntityFeedController.
 *
 * @package Drupal\my_module\Controller
 */
class CustomEntityFeedController extends ControllerBase {
    public function feed() {
        // Query for custom entities, loop through them, and build XML output.
        $xml = $xml_content_header . $xml_content . $xml_content_footer;
        $response = new Response();
        $response->headers->set('Content-Type', 'xml');
        $response->setContent($xml);
    }
}
id flag
Please share more of the code implementation. There is no context as to the location of those lines of code.
id flag
Also: what will cause the XML to change? It is impossible to answer this question minus that information.
in flag
@cilefen I've added some more context. A custom route implements the `feed` method to return the XML markup. The XML should generally only change if the queried entities are added/removed.
Alfred Armstrong avatar
cn flag
Because the content of the list depends on multiple entities you will need to either invalidate it whenever any such entity is added, removed or updated, or expire the cache based on time. I'd do the latter unless you absolutely need the feed to update immediately.
id flag
They can add the cache tags of the entities.
Score:1
cn flag

So you did already manage to return a cacheable response object, otherwise you wouldn't be able to produce this error message. The cause of the error is bubbled-up metadata, for example from an entity query with access checks or from a rendered URL. For each, you find solutions by searching for the error message. If not, you can put the entire XML processing in its own render context. See How to get cache metadata from nested render array when returning response?

Score:0
us flag

Instead of using a Response object, you need to use a \Drupal\Core\Cache\CacheableResponse object. The CacheableResponse class extends the Response class; it adds the addCacheableDependency() method can be used as in the following code.

$response = new CacheableResponse($user->label());
$response->addCacheableDependency($user);

What passed to addCacheableDependency() can be any object from which the cached data depends.

id flag
@Vecta You will have to reference the "custom entities" in the cacheable dependency. You didn't show that code so we can't answer fully.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.