refactor: use DTO and terminate middleware for better performance

- Add PageviewData readonly DTO class for type safety
- Update AnalyticsClient to accept PageviewData instead of array
- Move analytics sending to terminate() method (runs after response sent)
- Update all tests for new DTO pattern
This commit is contained in:
mathiaspalmqvist committed 2026-01-03 15:09:48 +01:00
1 parent 448ac3e4cf
commit e3911ca12c
6 files changed
+154 -116

No files matched your search

+24 -19
View File
@@ -4,9 +4,10 @@ namespace Mattitja\Analytics\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Log;
use Mattitja\Analytics\Data\PageviewData;
use Mattitja\Analytics\Services\AnalyticsClient;
use Symfony\Component\HttpFoundation\Response;
class AnalyticsMiddleware
{
@@ -26,6 +27,8 @@ class AnalyticsMiddleware
'twitterbot',
];
private ?PageviewData $pendingData = null;
/**
* Handle an incoming request and capture analytics data.
*/
@@ -34,13 +37,22 @@ class AnalyticsMiddleware
$response = $next($request);
if ($this->shouldCaptureAnalytics($request)) {
$data = $this->buildAnalyticsData($request);
$this->sendAnalytics($data);
$this->pendingData = $this->buildAnalyticsData($request);
}
return $response;
}
/**
* Handle tasks after the response has been sent to the browser.
*/
public function terminate(Request $request, Response $response): void
{
if ($this->pendingData !== null) {
$this->sendAnalytics($this->pendingData);
}
}
/**
* Determine if analytics should be captured for this request.
*/
@@ -136,34 +148,27 @@ class AnalyticsMiddleware
/**
* Build analytics data payload from request.
*/
protected function buildAnalyticsData(Request $request): array
protected function buildAnalyticsData(Request $request): PageviewData
{
$data = [
'k' => config('mattitja-analytics.site_key'),
'u' => $request->fullUrl(),
'ip' => $request->ip(),
'ua' => $request->userAgent() ?? '',
];
$referrer = $request->header('referer');
if (! empty($referrer)) {
$data['r'] = $referrer;
}
return $data;
return new PageviewData(
siteKey: config('mattitja-analytics.site_key'),
url: $request->fullUrl(),
ip: $request->ip(),
userAgent: $request->userAgent() ?? '',
referrer: $request->header('referer'),
);
}
/**
* Send analytics data to the API.
*/
protected function sendAnalytics(array $data): void
protected function sendAnalytics(PageviewData $data): void
{
try {
app(AnalyticsClient::class)->send($data);
} catch (\Exception $e) {
Log::error('Failed to send analytics data', [
'error' => $e->getMessage(),
'data' => $data,
]);
}
}