Skip to content

Commit 3e64639

Browse files
committed
Hierarchical cache tags and automatic invalidation on mutations
Mutating methods invalidate the request path at the HttpClient level. Cache entries are tagged hierarchically so parent path invalidation cascades to children.
1 parent f78309f commit 3e64639

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## [1.1.1] - 2026-03-26
4+
5+
### Changed
6+
- Mutating methods (POST, PATCH, DELETE) in `HttpClient` now automatically invalidate
7+
the cache for the request path
8+
- Cache entries use hierarchical `TagDependency` tags — invalidating a parent path
9+
(e.g. `/posts`) also clears all child entries (e.g. `/posts/1`)
10+
- `Resource::$cacheInvalidationPaths` now only handles cross-resource invalidation;
11+
per-path invalidation is handled by `HttpClient`
12+
313
## [1.1.0] - 2026-03-26
414

515
### Fixed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,9 +333,11 @@ and `cacheDuration` is greater than 0. Cache keys include both the request path
333333
parameters, so requests to the same endpoint with different parameters (e.g. `?expand=comments`
334334
vs. no expand) are cached independently.
335335

336-
Mutating operations (POST, PATCH, DELETE) in resources can invalidate related cache entries
337-
through the `$cacheInvalidationPaths` property. Invalidation uses Yii2's `TagDependency` to
338-
clear **all** parameter variants of a path at once.
336+
Mutating operations (POST, PATCH, DELETE) automatically invalidate the cache for the
337+
request path. Cache entries are tagged hierarchically, so invalidating a parent path
338+
(e.g. `/posts`) also clears all child entries (e.g. `/posts/1`).
339+
340+
Resources can define additional paths to invalidate via `$cacheInvalidationPaths`:
339341

340342
```php
341343
class PostResource extends Resource

src/HttpClient.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public function get(string $path, array $options = []): array
158158
$cacheKey,
159159
$data,
160160
$this->cacheDuration,
161-
new TagDependency(['tags' => [$this->getCacheTag($path)]])
161+
new TagDependency(['tags' => $this->getCacheTags($path)])
162162
);
163163
}
164164

@@ -168,17 +168,21 @@ public function get(string $path, array $options = []): array
168168
public function patch(string $path, array $options): true
169169
{
170170
$this->sendRequest('PATCH', $path, $options);
171+
$this->invalidateCache($path);
171172
return true;
172173
}
173174

174175
public function post(string $path, array $options): array
175176
{
176-
return $this->sendRequest('POST', $path, $options);
177+
$data = $this->sendRequest('POST', $path, $options);
178+
$this->invalidateCache($path);
179+
return $data;
177180
}
178181

179182
public function delete(string $path, array $options = []): true
180183
{
181184
$this->sendRequest('DELETE', $path, $options);
185+
$this->invalidateCache($path);
182186
return true;
183187
}
184188

src/traits/CacheInvalidation.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,23 @@ public function getCacheTag(string $path): string
3232
return 'httpclient:tag:' . md5(rtrim($this->baseUri, '/') . '/' . ltrim($path, '/'));
3333
}
3434

35+
/**
36+
* Generate hierarchical cache tags for a path.
37+
* Returns tags for the path and all parent paths, so invalidating
38+
* a parent (e.g. /person) also clears children (e.g. /person/123).
39+
*/
40+
public function getCacheTags(string $path): array
41+
{
42+
$segments = explode('/', trim($path, '/'));
43+
$tags = [];
44+
$current = '';
45+
foreach ($segments as $segment) {
46+
$current .= ($current ? '/' : '') . $segment;
47+
$tags[] = $this->getCacheTag($current);
48+
}
49+
return $tags;
50+
}
51+
3552
/**
3653
* Invalidate all cached variants for a specific path
3754
*/

0 commit comments

Comments
 (0)