core icon indicating copy to clipboard operation
core copied to clipboard

Cannot force client to cache authenticated responses using Entity cache properties

Open nathansalter opened this issue 1 year ago • 2 comments

API Platform version(s) affected: 2.7, 3.0

Description
The documentation is not particularly clear about this, but you cannot set the max-age property on authenticated responses. This isn't an issue with API Platform as such, it's a feature that's supplied by Symfony. Basically Symfony will override all cache headers sent to it for requests with a session, and set max-age=0, private, must-revalidate for the cache headers.

See this code snippet: https://github.com/symfony/http-kernel/blob/7.1/EventListener/AbstractSessionListener.php#L200

There are many valid cases for when you'd want Client Cache to be possible in an authenticated session, especially when working with SPAs and other Clients. You've got the s-maxage setting which is not overwritten, but that's only for people using a Cache such as Varnish.

How to reproduce
Simply add the following operation to an entity with security enabled:

        new GetCollection(
            security: 'is_granted(\'ROLE_USER\')',
            cacheHeaders: ['max_age' => 3600, 'shared_max_age' => 3600, 'public' => true, 'expires' => null],
        )

When making requests, the cache header will be:

max-age=0, must-revalidate, private, s-maxage=3600

Possible Solution
In ApiPlatform\HttpCache\EventListener\AddHeadersListener, simply set the AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER header if the max_age property is set for the operation. It seems like it should be safe to assume that in these cases the developer understands the implications of having cache set on the client.

Additional Context
I've written a shim in our codebase to add this header for certain entities, but it would be simpler to have this reflected directly from API Platform

nathansalter avatar Oct 16 '24 14:10 nathansalter

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Dec 15 '24 14:12 stale[bot]

I like your solution, wdyt @dunglas?

Would you be able to open a PR on main with your changes?

soyuka avatar Dec 16 '24 08:12 soyuka