API Reference

This guide is for those not using an Express.js backend but who want to track the backend duration of their requests.

To track your requests, create a middleware using the provided example for Express. Ensure that you allow the fetchlytics-id header.

We are working on expanding our support to other frameworks and libraries.

1export interface FetchAnalyticsOptions {
2	apiKey: string;
3	appName: string;
4}
5
6export function trackRequestAnalytics(options: FetchAnalyticsOptions) {
7	return (req: Request, res: Response, next: NextFunction) => {
8		// Extract the unique fetch identifier from the request headers
9		const fetchLyticsId = req.headers?.['fetchlytics-id'];
10
11		if (!fetchLyticsId) {
12			return next(); // Skip if no fetch identifier is found
13		}
14
15		// Track the start time of the request
16		const start = Date.now();
17
18		// Function to run when the response is finished
19		const onResponseFinished = async () => {
20			const fullUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;
21			const duration = Date.now() - start;
22			const analyticsData = {
23				fetchLyticsId,
24				appName: options.appName,
25				url: fullUrl,
26				method: req.method,
27				status: res.statusCode,
28				duration,
29				timestamp: start,
30			};
31
32			try {
33				// Dynamically import node-fetch only when needed
34				const fetch = (await import('node-fetch')).default;
35
36				// Send the analytics data
37				await fetch('https://fetchlytics.dev/api/datacollector/backendAnalytic', {
38					method: 'POST',
39					headers: {
40						'Content-Type': 'application/json',
41						Authorization: `Bearer ${options.apiKey}`,
42					},
43					body: JSON.stringify(analyticsData),
44				});
45			} catch (error) {
46				console.error('Failed to send backend analytics:', error);
47			}
48		};
49
50		// Attach the onResponseFinished function to the response finish
51		if (res.on) {
52			res.on('finish', onResponseFinished); // For Express or Fastify-like frameworks
53		} else if (typeof res.end === 'function') {
54			const originalEnd = res.end;
55			res.end = (...args: any[]) => {
56				onResponseFinished();
57				return originalEnd.apply(res, args); // Make sure to return the result of the original res.end function
58			};
59		}
60
61		next(); // Proceed to the next middleware
62	};
63}