php 45 lines · 8 steps

Caching HTTP responses with Laravel middleware

A middleware that serves cached responses for safe GET requests and stores fresh ones on the way out.

Explained by highlit
1<?php
2 
3namespace App\Http\Middleware;
4 
5use Closure;
6use Illuminate\Http\Request;
7use Illuminate\Support\Facades\Cache;
8use Symfony\Component\HttpFoundation\Response;
9 
10class CacheResponse
11{
12 public function handle(Request $request, Closure $next, int $ttl = 300): Response
13 {
14 if (! $request->isMethod('GET') || $request->hasHeader('Authorization')) {
15 return $next($request);
16 }
17 
18 $key = $this->cacheKey($request);
19 
20 if ($cached = Cache::get($key)) {
21 return response($cached['content'], $cached['status'])
22 ->withHeaders($cached['headers'])
23 ->header('X-Cache', 'HIT');
24 }
25 
26 $response = $next($request);
27 
28 if ($response->isSuccessful()) {
29 Cache::put($key, [
30 'content' => $response->getContent(),
31 'status' => $response->getStatusCode(),
32 'headers' => [
33 'Content-Type' => $response->headers->get('Content-Type'),
34 ],
35 ], now()->addSeconds($ttl));
36 }
37 
38 return $response->header('X-Cache', 'MISS');
39 }
40 
41 protected function cacheKey(Request $request): string
42 {
43 return 'response:'.sha1($request->fullUrl());
44 }
45}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Only cache idempotent, unauthenticated requests to avoid serving one user's data to another.
  2. 2An X-Cache header makes it easy to verify hits versus misses in production.
  3. 3Storing status, content, and headers together lets you faithfully reconstruct a response from cache.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Caching HTTP responses with Laravel middleware — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code