Implement the "HTTP Representation Variants" draft

Created on 1 April 2019, over 5 years ago
Updated 30 January 2023, almost 2 years ago

Problem/Motivation

  1. Since #2158003: Remove Block Cache API in favor of blocks returning #cache with cache tags (just over five years ago!), Drupal has the concept of "cache contexts".
  2. Cache contexts provide a declarative way to create context-dependent variations of something that needs to be cached

    Cache contexts are analogous to HTTP's Vary header.

    — see https://www.drupal.org/docs/8/api/cache-api/cache-contexts for more information

  3. Since #2458349: Route's access result's cacheability not applied to the response's cacheability , Drupal exposes the cache contexts that applied to the current response, i.e. describes along which aces a response varied.
  4. Now there is https://httpwg.org/http-extensions/draft-ietf-httpbis-variants.html, a draft HTTP RFC. A few quotes:

    This specification introduces an alternative way to communicate a secondary cache key for a HTTP resource, using the HTTP “Variants” and “Variant-Key” response header fields. Its aim is to make HTTP proactive content negotiation more cache-friendly.

    The Variants header field represents an ordered list of “variant-axes”, each of which consists of a request header “field-name”
    string and a list of “available-value” strings. Each inner-list in the Variants header field value is parsed into a variant-axis.

    Vary: Accept-Language
    Variants: Accept-Language;de;en;jp
    Variant-Key: en
    

    The Vary header we all know has its limitations: it's impossible for a HTTP cache to know which variations exist, and hence it's impossible for it to normalize the headers of incoming requests to match it up with a cached response. This is true for Accept-Language, but also for Accept for example, which is one of the reasons that Drupal went with a ?_format query argument in #2481453: Implement query parameter based content negotiation as alternative to extensions to negotiate a response format (Content-Type). Because many HTTP caches (at least at the time) were simply ignoring Accept request headers precisely because they were impossible to normalize. (More details at https://www.drupal.org/node/2501221 .)

  5. The new Variants and Variant-Key solve this:
    1. Variants lists exactly which variation axes exist and for each axis, which possible values exist for the current resource.
    2. Variant-Key lists exactly which combination of variations the current representation contains.
    3. Combining the information in Variants and Variant-Key, HTTP caches can overcome previous limitations, and for example Accept-based negotiation would become reliable if all HTTP caches in the path between the end user and the origin supported it.

    Proposed resolution

    We should implement this in Drupal to help vet the RFC before it becomes a standard.

    • Ideally, this would be an addition to our existing \Drupal\Core\Cache\Context\CacheContextInterface and \Drupal\Core\Cache\Context\CalculatedCacheContextInterface, since the concepts are connected.
    • However, a complication is that cache contexts operate at the level of the request context, without knowledge about the resource associated with the URL in the incoming request, and therefore also not with the variants available for that specific resource (and hence response). For example for the languages context correlates to the Content-Language response header, but right now Drupal sets that header based on the negotiated interface language, even though we may want to generate that for the content language, i.e. which languages a piece of content (a resource, such as an article) is available in.
    • Furthermore, most cache contexts in Drupal cannot be negotiated using request headers at all. So perhaps the implementation of this RFC should not be coupled to Drupal's "cache contexts" concept?

    Remaining tasks

    TBD

    User interface changes

    None.

    API changes

    None.

    Data model changes

    None.

    Release notes snippet

    TBD

Feature request
Status

Needs work

Version

10.1

Component
Request processing 

Last updated 7 days ago

No maintainer
Created by

🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

  • Needs change record

    A change record needs to be drafted before an issue is committed. Note: Change records used to be called change notifications.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • The Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

    Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

Production build 0.71.5 2024