dragon-code/last-modified
A small Laravel package for tracking last-modified timestamps and exposing them through HTTP headers, helping browsers, proxies, and caches avoid unnecessary re-downloads and stay in sync with your content.
Architecture fit. Unchanged. The package still targets a genuine gap in the Laravel HTTP layer: conditional requests (RFC 7232) are only partially covered by the framework. Laravel ships cache.headers / SetCacheHeaders for Cache-Control, and Symfony's HttpFoundation exposes Response::setEtag() / isNotModified(), but there is no first-class middleware that computes a validator from response content and short-circuits to 304 Not Modified. A middleware in the Illuminate\Contracts\Http\Kernel pipeline remains the correct insertion point. Nothing in 4.4.0 changes the shape of the solution.
Integration feasibility. Unchanged. composer require, register middleware globally or on a read-heavy route group, no migrations, no service-provider state. One engineer, under a day. The gating question is still ownership, not wiring.
Technical risk. Materially reduced but not resolved — revised from High to Moderate.
What 4.4.0 changes:
@andrey-helldar) with a merged community PR (#49), not by an automation bot alone. Either the repository was never archived, or it has been reactivated. This should be re-verified against the repo's current archived flag before we rely on either the old assessment or this one.composer.json constraint against our pinned version.What 4.4.0 does not change:
BinaryFileResponse, Octane, or chunked JSON. Adoption signal is unchanged; the compatibility bump is a maintenance signal, not an adoption signal.github-actions[bot]; the only functional change is the Laravel 13 constraint widening. There are no bug fixes and no behavioral changes, so every open functional question from the prior assessment survives intact.Key questions. (1)–(6) from the prior assessment remain fully open — this release answers none of them:
ETag (content hash), Last-Modified (timestamp), or both — and what is hashed (full body, updated_at, explicit override)?SetCacheHeaders, Vary, and a CDN edge in front of the app?304 ever bypass route auth/permission checks that run after the middleware?Response::setEtag()?New questions raised by 4.4.0: 7. Is the repository actually archived — was the prior finding wrong, or was it reactivated, and under what commitment? 8. Does the CI matrix actually include Laravel 13 and our PHP version, or was the constraint widened without a corresponding test lane? 9. Is there a stated support window or EOL policy, now that the package has demonstrated it will track new framework majors?
Stack fit. Unchanged. Clean fit for cacheable GET endpoints returning application/json or text/html — API list/detail resources, semi-static pages, polling clients. Poor fit for authenticated per-user responses, streaming/downloads, and anything already behind a well-tuned CDN with its own validator strategy.
Migration path. The recommendation softens from "fork-and-own (recommended)" to "adopt with a hard vendor hedge," though both remain viable:
4.4.x, but only behind our own middleware class name so the implementation is swappable without touching route definitions. Retain a vendored fork as a pre-planned contingency rather than the starting point. This is now defensible because the package is demonstrably alive and framework-current, which was the single biggest objection to adoption.http-cache package. The logic is small — compute validator, compare against If-None-Match / If-Modified-Since, emit 304 with correct headers — so reimplementation remains cheaper than carrying a dependency we don't trust for a 30-line behavior. Choose this if the open functional questions (validator source, Octane safety, auth ordering) can't be answered from the source in a code read.Compatibility. Re-verify explicitly — the release note is a claim, not a certificate:
composer.json constraint covers our exact Laravel minor and PHP version, not just "Laravel 13."Response::setEtag().Sequencing. Unchanged, and the release does not justify skipping any step:
304/200 paths; confirm Vary and Cache-Control interaction.304 rate per route without serving 304.GET routes; measure egress, p95 latency, CPU.Because 4.4.0 shipped no behavioral fixes, the spike and shadow phases are not de-risked by this release — they must still run at full scope.
Maintenance. Downgraded from "we inherit 100% of maintenance" to "shared, but fragile." The maintainer is still shipping framework compatibility, so routine version-bump work is no longer automatically ours. But the release profile — one substantive PR against four automated cosmetic commits — means there is no evidence of an active bug-fix backlog, and no published support window. Budget a named internal owner, a CI job that exercises our Laravel/PHP combination on every framework upgrade, and a scheduled review each Laravel major. Keep the fork contingency warm, not cold.
Support. Improved only marginally. There is now evidence of a responsive maintainer merging external PRs, which makes upstream contribution a plausible escalation path — but there is still no issue triage SLA, no security advisory process, and no dependents to corroborate fixes. Internal escalation must still be defined before production enablement; a 304 bug remains a correctness incident, not a performance one.
Scaling. Unchanged. Benefits scale with payload size and client count (fewer bytes, better mobile latency, lower egress). Costs scale with request count: hashing the full response body is O(body) CPU per request and can dominate on large JSON payloads or high-RPS endpoints. Prefer updated_at-derived validators over body hashing for DB-backed content, and confirm buffering behavior — a middleware that forces buffering on streamed responses can raise memory ceilings under load. Nothing in 4.4.0 touches this.
Failure modes. Unchanged, and none are remediated by a compatibility-only release:
304 — content changes without a validator change (e.g., related-model data that doesn't touch the parent's updated_at). Serving stale data is worse than the perf gain; prefer body-hash ETag where staleness risk is high.304 returned before authorization is evaluated, or a shared cache storing one user's validator. Enforce Cache-Control: private and correct Vary; never apply to authenticated endpoints without review.ETag semantics at the CDN causing oscillation between 200 and 304.Ramp-up. Unchanged and trivial at the code level — a mid-level Laravel engineer can read and reason about the middleware in a few hours. The organizational ramp-up remains the real work: assigning ownership (now "maintain a fork contingency and a version-bump review" rather than "own the fork outright"), defining eligible routes, and adding 304 rate plus stale-content alarms to observability before the first production request.
Bottom line. Upgraded from "sound idea, unusable dependency" to "sound idea, viable dependency with a maintained hedge." 4.4.0 retires the strongest objection — abandonment — by demonstrating a maintainer actively tracking framework majors, so adopt-with-pinning behind an internal middleware wrapper is now a reasonable default rather than a stopgap. It does not retire the second-strongest objection: zero production validation and one unanswered question about validator semantics, auth ordering, and Octane safety. Ship it only behind measurement, restricted to unauthenticated cacheable GET routes, with a fork contingency kept warm.
How can I help you explore Laravel packages today?