Problem/Motivation

Cache settings provided by the views config are not rendered in the headers of the JSON output, which means that the display's cache does not get invalidated when it should.

Steps to reproduce

  1. Create a JSON:API view.
  2. Set the View caching to tag-based.
  3. View the headers of the rendered view -- the views cache tags will not be listed.

This affects both the basic Views cache tags, and custom tags provided by Views Custom Cache Tags.

Time-based cache settings are also not bubbling up.

Proposed resolution

Explicitly adding the view's cache tags using $bubbleable_metadata->addCacheTags($view->getCacheTags()); fixes the problem for tag-based caching. I'm not sure how to access the time-based caching settings or send them to the headers.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jesss created an issue. See original summary.

jesss’s picture

StatusFileSize
new522 bytes

Patch attached.

deciphered’s picture

Status: Active » Needs review
Issue tags: +Needs tests

Thanks for the patch, will test and review.

artem_sylchuk’s picture

StatusFileSize
new869 bytes

Not sure if separate issue should be opened but proposed patch doesn't fix the cache contexts.
If any of the view plugins implements the CacheableDependencyInterface::getCacheContexts the context won't be added to the response.
So, for example if you have a view with the uid contextual filter that provides default value set to "current user", the [user] context won't be added to a response leading to the potential exposing user's data.

I tried to fix that and found that few things are wrong there.

<?php
    if (!$context->isEmpty()) {
      $bubbleable_metadata = $context->pop();
      BubbleableMetadata::createFromObject($view->result)
        ->merge($bubbleable_metadata);
    }
    else {
      $bubbleable_metadata = BubbleableMetadata::createFromObject($view->result);
    }
?>

$view->result is a Drupal\views\ResultRow object that doesn't implement the CacheableDependencyInterface, so according CacheableMetadata::createFromObject cacheMaxAge will be set to 0.
Also BubbleableMetadata::merge doesn't modify the object, you must use the return result. Seems 2 bugs avoided each other.

So instead of trying to build the cache object from view->result I used $view->element instead (However I'm not sure if it is the proper place to look for the caching metadata).
Patch attached (will use the issue fork the next time).

Status: Needs review » Needs work

The last submitted patch, 4: jsonapi_views-cachebility-3202583-4.patch, failed testing. View results

artem_sylchuk’s picture

Wow, tests say that I'm terribly wrong even it seems to work for me

artem_sylchuk’s picture

Looks like now the [url] cache context is added and url.query_args and other more specific contexts are ignored during the merging.
Not sure if problem is in tests or cache contexts.

deciphered’s picture

@jesss,

I tested the patch locally and it appears to resolve issue that I can reproduce. However, the patch does still need a test that proves the issue. As this issue needs to be resolved I will start work on the test shortly.

@artem_sylchuk,

It's possible that both solutions resolve the issue, but that your solution may solve additional issues, which is great. I don't have a high enough understanding of your specific issues, but if you are able to provide me with some automated tests or reproducible steps I should be able to help more.

artem_sylchuk’s picture

@Deciphered
The simpliest reproducable steps are the following:
1. Create the view showing nodes
2. Add the contextula filter by node author
3. in the WHEN THE FILTER VALUE IS NOT AVAILABLE of the contextual filter select Provide default value: User ID from logged in user
4. Create 2 users A and B. Create a few nodes by each.
5. Confirm that user A sees only own nodes when visits the view page, same for user B
6. Expose the view via Jsonapi:views
7. Check the Jsoapi response for the user A
8. Check the Jsoapi response for the user B (you'll see the same nodes as for the user A in the current version of the module)

I can try providing test for this the next week

  • Deciphered committed 2938604 on 8.x-1.x authored by jesss
    Issue #3202583 by jesss: Views cache settings not added to headers
    
  • Deciphered committed 47b0630 on 8.x-1.x
    Issue #3202583: Added test for cache tags.
    
deciphered’s picture

Thanks for getting back to me so quickly @artem_sylchuk

I did just push @jesss' patch with an automated test, but I will run through those steps now and see what I can see.

bladedu’s picture

StatusFileSize
new882 bytes

patch #4 bump to be compatible with release 1.0

yahyaalhamad’s picture

Priority: Normal » Major
Status: Needs work » Needs review
StatusFileSize
new2.28 KB

This is an old issue, but I had problems with caching when different users are logged in, and other times, a 403 error is cached, this patch attempts to fix the issue by adding the dependency using the view render array, I made sure to also add the cache contexts to fix the issue of different users when attempting to use the API. Also, make sure to add cache dependency when the view access is denied.

anybody’s picture

Status: Needs review » Needs work

@yahyaalhamad thanks, could you maybe add a MR with your patch and add .gitlab-ci.yml to see if the tests turn green then?

@deciphered are you still actively maintaining this module?

deciphered’s picture

Status: Needs work » Needs review

Sorry for the quiet spell here, I'm back and actively working through the backlog across all my modules, this one included.

MR is up: cache tags, contexts and max-age are now derived from the view's own render array instead of the broken $view->result based collection. The user-context leak artem_sylchuk found is fixed, and 403 responses now carry proper cacheability too. Tests green on D10 and D11.

  • deciphered committed 13ab11b2 on 8.x-1.x
    fix(#3202583): skip view execution for access-denied requests
    

deciphered’s picture

Status: Needs review » Fixed

Thanks all, fixed and committed for the upcoming 8.x-1.2 release.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.