Skip to content

refactor(cache)!: add CacheKey as the one encoder and parser of HTTP keys - #405

Merged
allen0099 merged 1 commit into
masterfrom
refactor/270-cache-key-type
Sep 29, 2026
Merged

allen0099 merged 1 commit into
masterfrom
refactor/270-cache-key-type

Conversation

@allen0099

Copy link
Copy Markdown
Owner

Closes #270. This is step 1 of the 0.4.0 cache-key work (#271, #266, #265, #269, #72 follow).

What changes

  • New public CacheKey (fastapi_cachex.CacheKey, module fastapi_cachex/cache_key.py), a frozen dataclass with:
    • from_request(request, *components, sort_query=...): the key @cache stores a request under;
    • to_str(): the single encoder;
    • parse(key): the single decoder. It returns None for keys that are not HTTP keys;
    • path_glob(path): the Redis glob for "every key with this path".
  • build_cache_key() is now CacheKey.from_request(...).to_str(). The monitoring routes, MemoryBackend.clear_path and AsyncRedisCacheBackend.clear_path use CacheKey.parse / path_glob instead of splitting keys themselves.
  • Removed: CACHE_KEY_MIN_PARTS, CACHE_KEY_MAX_SPLIT and CACHE_KEY_MAX_PARTS from fastapi_cachex.routes (maintainer decision: remove outright in 0.4.0).

The stored format does not change

Keys stay method|||host|||path|||query|||extra... and sort_query still defaults to False. A golden-string test pins the format, so the follow-up PRs change it on purpose. There are three small deltas:

  • The method is percent-encoded like host and path. A method token may contain |. Without the encoding, build_cache_key() / invalidate() on such a request would produce an unparseable key, and with the new validation would raise. Real methods (GET, ...) are unaffected.
  • CacheKey.query may not contain the separator (ValueError). A query taken from a request never does, because Starlette encodes |.
  • clear_path compares the decoded path rather than the escaped one, and no longer treats a key with an empty method as an HTTP key. This makes no difference for keys written by build_cache_key. Only hand-written, non-canonically escaped keys could behave differently.

Tests and docs

  • tests/test_cache_key_type.py: round trips, non-HTTP keys, escaping, validation, path_glob, the pinned format. Each assertion was checked by breaking the code it guards.
  • Existing tests that imported routes._parse_cache_key / _split_cache_key now use CacheKey.parse.
  • Docs: HTTP_CACHING.md (new CacheKey paragraph), MIGRATING_0_4.md, API reference, and the zh-TW counterparts.
  • Changelog: changelog.d/270.added.md, changelog.d/270.removed.md.

Checks: pre-commit, mypy tests, mypy scripts, both strict docs builds, and the full suite with live Redis and Memcached (99.82% coverage).

…keys

The key format was built in build_cache_key but parsed separately in the
monitoring routes, memory clear_path and the Redis clear_path glob. Add a
public frozen CacheKey (from_request, to_str, parse, path_glob) and route
all of them through it. The stored format does not change: the upcoming
0.4.0 key changes (#271, #266, #265, #269, #72) then touch one module.

The method is now percent-encoded like host and path, so a method token
containing "|" cannot shift the components; real methods are unchanged.

BREAKING CHANGE: CACHE_KEY_MIN_PARTS, CACHE_KEY_MAX_SPLIT and
CACHE_KEY_MAX_PARTS are removed from fastapi_cachex.routes; use
CacheKey.parse(key).

Closes #270
@allen0099 allen0099 added this to the 0.4.0 milestone Sep 29, 2026
@allen0099 allen0099 added enhancement New feature or request http-cache The @cache decorator, cache keys and Cache-Control handling breaking-change Changes public behaviour or API; needs a minor/major release labels Sep 29, 2026
@allen0099
allen0099 merged commit 00802b9 into master Sep 29, 2026
15 checks passed
@allen0099
allen0099 deleted the refactor/270-cache-key-type branch September 29, 2026 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Changes public behaviour or API; needs a minor/major release enhancement New feature or request http-cache The @cache decorator, cache keys and Cache-Control handling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cache key: a single CacheKey type to encode and parse the format

1 participant