Express Adapter
Section titled “ Express Adapter”Full-featured adapter for Express.js with middleware support, request context, and authentication helpers.
Drizzle Cube adapters integrate seamlessly with popular web frameworks, providing framework-specific optimizations while maintaining consistent semantic layer functionality.
Choose the adapter that matches your web framework:
Full-featured adapter for Express.js with middleware support, request context, and authentication helpers.
High-performance adapter optimized for Fastify’s plugin system with built-in schema validation.
Lightweight adapter for Hono framework, perfect for Cloudflare Workers and edge computing environments.
Full-stack adapter with App Router support, server components integration, and optimized client-side caching.
All adapters provide:
Drizzle Cube adapters follow a consistent pattern:
import { createCubeRouter } from 'drizzle-cube/adapters/express'
const cubeRouter = createCubeRouter({ cubes: [usersCube, ordersCube, productsCube], drizzle: db, schema, // Called for EVERY request - your security boundary extractSecurityContext: async (req, res) => ({ organisationId: req.user.orgId, userId: req.user.id })});
app.use('/', cubeRouter); // defaults to /cubejs-api/v1Each adapter exposes the same options under its own factory - createCubeRouter / createCubeApp (Express), cubePlugin / createCubeApp (Fastify), createCubeApp (Hono) and createCubeHandlers (Next.js).
All four adapters accept a pre-built semanticLayer instead of cubes. This is how an application opts into per-tenant cube sets, since it must own the SemanticLayerCompiler to call registerCubeSet:
import { SemanticLayerCompiler } from 'drizzle-cube/server'
const semanticLayer = new SemanticLayerCompiler({ drizzle: db, schema, contextToCubeSetId: (ctx) => String(ctx.organisationId)});
semanticLayer.registerCube(usersCube);semanticLayer.registerCubeSet('org-123', [customOrdersCube]);
const cubeRouter = createCubeRouter({ semanticLayer, drizzle: db, schema, extractSecurityContext });GET /meta resolves extractSecurityContext like every other route and returns only that tenant’s cubes. Two consequences even if you change no code:
/meta now invokes your extractor. It previously did not. If your extractor throws for unauthenticated requests, anonymous /meta calls will fail - return SINGLE_TENANT_CONTEXT (from drizzle-cube/server) for anonymous requests if you want metadata to stay public./meta is no longer publicly cacheable. Every REST response (/meta, /load, /sql, /dry-run, /batch, /explain) now sets Cache-Control: private, no-store, so none of them may be stored in a shared cache or CDN keyed on URL alone.Need support for a different framework? Check out our guide on building custom adapters to integrate Drizzle Cube with any web framework.
Each adapter includes comprehensive documentation with setup guides, configuration options, and integration examples.