Problem/Motivation

The change introduced in this issue https://www.drupal.org/project/rest_menu_items/issues/3039979 in comments #24 and #25 made the response of the resource uncacheable by browser. If you check the headers of the response you will see "Cache-Control: must-revalidate, no-cache, private". This is expected because of ModifiedResourceResponse, see class web/core/modules/rest/src/ModifiedResourceResponse.php:

/**
 * A response that does not contain cacheability metadata.
 *
 * Used when resources are modified by a request: responses to unsafe requests
 * (POST/PATCH/DELETE) can never be cached.
 *
 * @see \Drupal\rest\ResourceResponse
 */
class ModifiedResourceResponse extends Response implements ResourceResponseInterface {

For this reason when calling the endpoint next time, browser tries to load the menu again. Also it is not possible to use CDN with such response headers.

Steps to reproduce

Install the module.
Enable rest resource.
Try to load the main menu like this: /api/menu_items/main .
Observe response headers, see that response is uncacheable.

Proposed resolution

- stop using ModifiedResourceResponse - it's for POST/PUT requests, it's not intended for GET responses
- fix cache metadata to correct cache-invalidation

Remaining tasks

User interface changes

None.

API changes

None.

Data model changes

None.

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

a.dmitriiev created an issue. See original summary.

useernamee’s picture

StatusFileSize
new1.83 KB

I reverted the use of ModifiedResourceResponse.

useernamee’s picture

StatusFileSize
new3.67 KB

Wrong patch. Fix coming soon.

useernamee’s picture

useernamee’s picture

StatusFileSize
new2.8 KB

fago made their first commit to this issue’s fork.

fago’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new8.25 KB

So instead of using an uncacheable response, it shoudl have correct cache-metadata. added this.
attaching a copy of the change for composer-patches usage.

fago’s picture

The MR has some phpstan fails which are unrelated. opened #3566606: Deprecations cause phpstan errors for that.

Then there is a phpunit test checking cache headers which needs to be updated. Done so. Note: I used AI to help with this.

ciprian.stavovei’s picture

Status: Needs review » Reviewed & tested by the community

The fix is working correctly, the caching is added now: cache-control: max-age=60, public, s-maxage=2764800.

batigolix’s picture

Status: Reviewed & tested by the community » Fixed

I tested this as well.

On the 3.0.x branch:

curl -sI -k 'https://example.ddev.site/api/menu_items/main?_format=json'                                                            
HTTP/2 200 
cache-control: must-revalidate, no-cache, private
content-language: en
content-type: application/json
date: Sun, 01 Feb 2026 09:52:36 GMT
expires: Sun, 19 Nov 1978 05:00:00 GMT
server: nginx
x-content-type-options: nosniff
x-drupal-cache: UNCACHEABLE (no cacheability)
x-drupal-dynamic-cache: UNCACHEABLE (no cacheability)
x-frame-options: SAMEORIGIN
x-generator: Drupal 11 (https://www.drupal.org)
content-length: 244

On the issue branch 3482637-response-of-the:

curl -sI -k 'https://example.ddev.site/api/menu_items/main?_format=json'                                          
HTTP/2 200 
cache-control: max-age=600, public
content-language: en
content-type: application/json
date: Sun, 01 Feb 2026 09:53:37 GMT
etag: "1769939617"
expires: Sun, 19 Nov 1978 05:00:00 GMT
last-modified: Sun, 01 Feb 2026 09:53:37 GMT
server: nginx
vary: Cookie
x-content-type-options: nosniff
x-drupal-cache: HIT
x-drupal-dynamic-cache: MISS
x-frame-options: SAMEORIGIN
x-generator: Drupal 11 (https://www.drupal.org)
content-length: 244

I ll merge this and close the issue.

Many thanks for your help.

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.

  • batigolix committed 124e6ee1 on 3.0.x authored by fago
    feat: #3482637 Response of the rest resource is uncacheable by browser...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.