ClickHouse Express

Mount typed ClickHouse analytics on your Express.js server

Most backend teams already have an Express.js server. Adding ClickHouse analytics means writing route handlers, request validation, auth extraction, and documentation. @hypequery/serve provides a framework-agnostic handler that you can mount in Express with the Node adapter — validated inputs, typed responses, and OpenAPI docs included.

Framework

Express.js

Package

@hypequery/serve

Best for

Adding analytics to existing APIs

Writing Express routes for ClickHouse means raw SQL and untyped responses

The standard path is: write a raw SQL query, call @clickhouse/client, cast the response to an interface you defined manually, then return it. Every analytics route in the codebase follows this pattern — and every one is slightly different.

Every analytics route reimplements the same auth and tenant extraction boilerplate

Each route reads the Authorization header, verifies the JWT, extracts the tenantId, and injects it into the WHERE clause. This is identical logic repeated across dozens of routes, and any change to the auth flow requires touching each one.

No documentation for ClickHouse Express routes means frontend teams guess response shapes

Without a schema or OpenAPI spec, the frontend team reads the Express source code to understand what each analytics endpoint returns. When a ClickHouse column changes, there's no warning — the frontend just breaks.

How @hypequery/serve works with Express

Define analytics queries once — mount them on Express as typed endpoints

initServe() takes a context factory that runs per-request. It reads tenant and auth information from the Express request and makes it available to every query. You define analytics queries with the query() function — each one gets Zod input validation and a typed ClickHouse query builder. Then you expose the resulting `api.handler` through `createNodeHandler()` and mount that in Express.

  • initServe() context factory runs per-request — reads JWT, session, or headers
  • query() definitions include Zod input validation and typed ClickHouse queries
  • createNodeHandler(api.handler) mounts the generated HTTP surface in Express
  • OpenAPI spec generated automatically from input/output types
  • Interactive Swagger UI available at /[prefix]/docs with no additional setup

Query definitions

Define analytics queries with initServe

how-hypequery-serve-works-with-express.ts

Context is injected per-request — the auth middleware sets req.tenant, and the context factory reads it. Every query definition has access to db and tenantId without re-implementing extraction logic.

Express integration

Mount analytics routes alongside your existing Express server

createNodeHandler(api.handler) returns a Node-compatible request handler. You mount it on a path like /analytics alongside your existing routes. The analytics handler does not interfere with the rest of the Express app — it handles its own validation, error responses, and documentation.

Auth middleware runs before the analytics middleware and attaches tenant context to the request. The initServe() context factory reads that context and makes it available to all query definitions. One auth change propagates to every analytics endpoint.

The generated OpenAPI spec is available at /analytics/openapi.json. Use it to generate TypeScript client types for your frontend, validate integration tests against the schema, or import it into API gateway tooling.

Express server

Full Express server with mounted analytics routes

express-integration.ts

Existing routes are untouched. The analytics handler mounts on /analytics with auth applied upstream. OpenAPI docs are available immediately after startup.

Where teams usually get stuck

Questions teams ask

ClickHouse Express.js TypeScript

Adding analytics to Express is mostly an integration problem: validation, auth context, response contracts, and documentation. The query definitions stay separate from the framework glue.

Express analytics API ClickHouse

A production Express analytics API needs consistent auth injection, input validation, and typed response schemas. The useful pattern is one named query definition per metric, not route logic scattered across handlers.

ClickHouse REST Express

If you're serving ClickHouse data from Express, the win is not avoiding all code. It is avoiding repeated boilerplate for validation, docs, and response typing around each analytics route.

Express ClickHouse query builder

The query builder is framework-agnostic, which is the important part. Express is just one host for the handler, not the place your ClickHouse query logic has to live forever.

Next step

Mount analytics on your Express server in under 30 minutes

Install @hypequery/serve, generate your schema with the CLI, define your first analytics query, and mount it on your Express app. OpenAPI docs are available immediately — no extra configuration.