Skip to content

feat: return the whole cache from GET /layer/{layerName}/{cacheType} MAPCO-11508 - #174

Closed
razbroc wants to merge 2 commits into
masterfrom
feat/get-cache-whole-cache
Closed

feat: return the whole cache from GET /layer/{layerName}/{cacheType} MAPCO-11508#174
razbroc wants to merge 2 commits into
masterfrom
feat/get-cache-whole-cache

Conversation

@razbroc

@razbroc razbroc commented Aug 23, 2026

Copy link
Copy Markdown
Contributor
Question Answer
Bug fix
New feature
Breaking change
Deprecations
Documentation
Tests added
Chore

Further information:

GET /layer/{layerName}/{cacheType} returned only the cache source — the inner cache section of a mapproxy cache. It now returns the whole cache as written in the configuration, alongside its name.

"Cache" means two things in a mapproxy config: the entry under caches: (sources, grids, format, upscale_tiles, …) and its inner cache: key that names the storage backend. This endpoint only ever exposed the second one.

{
  "cacheName": "example-layer",
  "cache": { "type": "s3", "directory": "", "directory_layout": "tms" },
  "sources": [], "grids": ["epsg4326dir"], "format": "image/png", "upscale_tiles": 18
}

Not a breaking change

The cache source stays at the same cache key, so existing consumers read response.cache.* unchanged — the new fields are purely additive siblings. The only thing that would break is a consumer rejecting unknown response properties; none is known to.

The cache is spread verbatim, so mapproxy options we do not model (meta_size, cache_dir, …) are returned too. The response contract is deliberately "whatever the configuration holds" rather than our model of it — additionalProperties is left open and only cacheName + cache are required.

cacheType keeps its existing dual role unchanged: it selects the cache (-redis suffix) and validates it (400 when the resolved cache is of a different type).

Also in this PR

  • caches was mistyped (separate commit). IMapProxyJsonDocument.caches was declared as a single IMapProxyCache instead of a map of them, so every caches[name] lookup resolved to any through the index signature and the casts around them were unchecked. Now Record<string, IMapProxyCache>, which typed four test lookups that had been silently any.
  • ICacheObject/ICacheNameIGetCacheResponse. The request handler declared ICacheName as its response type while the manager returned ICacheObject — the response type was wrong. ICacheName had no other users.
  • Guard for malformed cache entries. A caches entry that is not an object, or an object with no cache source, reached .cache.type and produced a 500 — and under verbatim spread would have produced corrupt output. It now raises the existing NotFoundError.
  • Missing gpkgCache response schema. geopackage is an accepted cacheType, but getCacheResponse.cache had no geopackage variant and no discriminator mapping for it, so a real geopackage cache would have failed schema validation. Added with mapproxy's own option set and defaults (filename, table_name, levels, directory — all optional, type alone required).
  • Fixed a test that asserted NotFoundError where the code throws BadRequestError; it passed only because Jest's toThrow(errorInstance) compares the message, not the class.

Verification

tsc clean · 47 unit + 19 integration tests passing · eslint 0 problems · redocly lint valid. The typing-fix commit was checked to build, lint, and pass tests standalone before the feature commit went on top.

IMapProxyJsonDocument.caches was typed as a single IMapProxyCache rather
than a map of them, so every caches[name] lookup resolved to any through
the index signature, and the casts around those lookups were unchecked.
The endpoint returned only the cache source, the inner 'cache' section of
a mapproxy cache. It now returns the whole cache as it is written in the
configuration, alongside its name.

The cache source stays at the same 'cache' key, so existing consumers
read it unchanged and the new fields are additive. The cache is spread
verbatim, so mapproxy options we do not model are returned too.

Also:
- ICacheObject and the unused ICacheName become IGetCacheResponse, which
  the request handler now actually declares as its response type.
- a caches entry that is not an object, or holds no cache source, raises
  the existing NotFoundError instead of a 500 or a corrupt response.
- adds the missing gpkgCache response schema, since geopackage is an
  accepted cacheType, with mapproxy's own option set and defaults.
@razbroc razbroc changed the title feat: return the whole cache from GET /layer/{layerName}/{cacheType} feat: return the whole cache from GET /layer/{layerName}/{cacheType} MAPCO-11508 Aug 23, 2026
@razbroc razbroc closed this Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant