Framework Middleware

Framework middleware for automatic analytics integration

Framework Middleware

Middleware packages provide automatic analytics integration for popular web frameworks. Track requests, responses, user sessions, and custom events without manual instrumentation.

Node.js Middleware

Python Middleware

Quick Setup

Express.js

import express from 'express'
import { entrolyticsMiddleware } from '@entrolytics/express-middleware'

const app = express()

app.use(
  entrolyticsMiddleware({
    websiteId: 'your-website-id',
    apiKey: 'your-api-key'
  })
)

Fastify

import fastify from 'fastify'
import { entrolyticsPlugin } from '@entrolytics/fastify-middleware'

const app = fastify()

await app.register(entrolyticsPlugin, {
  websiteId: 'your-website-id',
  apiKey: 'your-api-key'
})

Flask

from flask import Flask
from entrolytics_flask import Entrolytics

app = Flask(__name__)
entrolytics = Entrolytics(app,
    website_id='your-website-id',
    api_key='your-api-key'
)

Laravel

// config/app.php
'providers' => [
    // ...
    Entrolytics\Laravel\EntrolyticsServiceProvider::class,
],

// middleware
'entrolytics' => \Entrolytics\Laravel\Middleware\TrackRequest::class,

Features

All middleware packages provide:

Automatic Tracking

  • Request/Response Tracking: Automatically track HTTP requests and responses
  • Page View Tracking: Track page views for server-rendered applications
  • User Identification: Identify users from sessions or authentication
  • Error Tracking: Automatically track application errors and exceptions
  • Performance Monitoring: Track response times and performance metrics

Custom Events

// Express
req.entrolytics.track('custom_event', { property: 'value' })

// Flask
@entrolytics.track('button_click')
def handle_click():
    pass

// Laravel
entrolytics()->track('form_submit', ['form_type' => 'contact']);

User Identification

// Express
req.entrolytics.identify('user-123', { email: 'user@example.com' })

// Flask
entrolytics.identify('user-123', email='user@example.com')

// Laravel
entrolytics()->identify('user-123', ['email' => 'user@example.com']);

Configuration

Common Options

interface MiddlewareConfig {
  websiteId: string
  apiKey?: string
  autoTrack?: boolean // Auto-track requests (default: true)
  trackErrors?: boolean // Track exceptions (default: true)
  trackPerformance?: boolean // Track response times (default: true)
  excludePaths?: string[] // Exclude specific paths
  includeHeaders?: string[] // Include specific headers
  debug?: boolean // Enable debug logging
}

Environment Variables

ENTROLYTICS_WEBSITE_ID=your-website-id
ENTROLYTICS_API_KEY=your-api-key
ENTROLYTICS_AUTO_TRACK=true
ENTROLYTICS_DEBUG=false

Advanced Usage

Custom Middleware Logic

Express.js

app.use((req, res, next) => {
  // Custom tracking logic
  if (req.user) {
    req.entrolytics.identify(req.user.id, {
      email: req.user.email,
      role: req.user.role
    })
  }

  // Track custom properties
  req.entrolytics.track('api_request', {
    method: req.method,
    endpoint: req.path,
    version: req.headers['api-version']
  })

  next()
})

Flask

@app.before_request
def before_request():
    if hasattr(g, 'user'):
        entrolytics.identify(g.user.id, {
            'email': g.user.email,
            'role': g.user.role
        })

    entrolytics.track('api_request', {
        'method': request.method,
        'endpoint': request.endpoint
    })

Laravel

// app/Http/Middleware/AnalyticsMiddleware.php
public function handle($request, Closure $next) {
    if ($request->user()) {
        entrolytics()->identify($request->user()->id, [
            'email' => $request->user()->email,
            'role' => $request->user()->role
        ]);
    }

    entrolytics()->track('api_request', [
        'method' => $request->method(),
        'endpoint' => $request->path()
    ]);

    return $next($request);
}

Error Tracking

Express.js

app.use((error, req, res, next) => {
  req.entrolytics.track('error', {
    message: error.message,
    stack: error.stack,
    url: req.url,
    method: req.method
  })

  next(error)
})

Flask

@app.errorhandler(500)
def handle_error(error):
    entrolytics.track('error', {
        'message': str(error),
        'url': request.url,
        'method': request.method
    })
    return "Internal Server Error", 500

Laravel

// app/Exceptions/Handler.php
public function report(Throwable $e) {
    entrolytics()->track('error', [
        'message' => $e->getMessage(),
        'class' => get_class($e),
        'url' => request()->fullUrl(),
        'method' => request()->method()
    ]);

    parent::report($e);
}

Performance Considerations

Async Operations

// Express - async tracking
app.use(
  entrolyticsMiddleware({
    websiteId: 'your-website-id',
    async: true // Don't block request processing
  })
)

Batch Tracking

// Batch multiple events
app.use((req, res, next) => {
  const events = [
    { event: 'request_start', properties: { url: req.url } },
    { event: 'user_agent', properties: { ua: req.headers['user-agent'] } }
  ]

  req.entrolytics.trackBatch(events)
  next()
})

Conditional Tracking

app.use((req, res, next) => {
  // Only track authenticated users
  if (req.user) {
    req.entrolytics.track('authenticated_request')
  }

  // Exclude health checks
  if (req.path !== '/health') {
    req.entrolytics.track('api_call')
  }

  next()
})

Testing

Unit Tests

// Express middleware test
import request from 'supertest'
import { EntrolyticsApiMockClient } from '@entrolytics/api-client/testing'

jest.mock('@entrolytics/express-middleware')

describe('Analytics Middleware', () => {
  it('should track requests', async () => {
    const mockTrack = jest.fn()
    EntrolyticsApiMockClient.prototype.track = mockTrack

    await request(app).get('/test').expect(200)

    expect(mockTrack).toHaveBeenCalledWith('request', {
      method: 'GET',
      path: '/test'
    })
  })
})

Integration Tests

# Flask middleware test
def test_middleware_tracks_requests(client):
    with patch('entrolytics_flask.Entrolytics.track') as mock_track:
        response = client.get('/test')

        assert response.status_code == 200
        mock_track.assert_called_once()

Best Practices

Migration Guides

From Manual Tracking

// Before
app.post('/signup', (req, res) => {
  // Manual tracking
  analytics.track('signup', req.body)

  // Handle signup
  handleSignup(req.body)
})

// After with middleware
app.post('/signup', (req, res) => {
  // Automatic tracking + custom properties
  req.entrolytics.track('signup', req.body)

  // Handle signup
  handleSignup(req.body)
})

Between Frameworks

# Flask to Laravel migration
# Flask
@app.route('/api/data')
def get_data():
    entrolytics.track('api_call', {'endpoint': '/api/data'})
    return jsonify(data)

# Laravel
Route::get('/api/data', function () {
    entrolytics()->track('api_call', ['endpoint' => '/api/data']);
    return response()->json($data);
});

Troubleshooting

Next Steps

  • Choose the right middleware for your framework
  • Follow the specific installation guide
  • Configure tracking for your use case
  • Implement custom tracking logic
  • Set up monitoring and alerts

Framework middleware for Entrolytics - First-party growth analytics for the edge