HTTP + OpenAPI
Expose hypequery metrics through HTTP handlers and autogenerated docs
HTTP + OpenAPI Delivery
We've simplified the serve API in v0.2. If you're looking for the older builder-first API, see Migrate from v0.1.x Serve API and v0.1.x Serve API.
hypequery can expose your queries as HTTP endpoints with automatically generated OpenAPI documentation.
Quick Example
Here's a complete example of exposing a query via HTTP:
1. Define your query:
// src/analytics/queries.ts import { initServe } from '@hypequery/serve'; import { z } from 'zod'; import { db } from './client'; const { query, serve } = initServe({ context: () => ({ db }), }); const revenue = query({ description: 'Get total revenue', output: z.object({ total: z.number(), count: z.number(), }), query: async ({ ctx }) => { const rows = await ctx.db .table('orders') .sum('amount', 'total') .count('order_id', 'count') .execute(); return rows[0]; }, }); export const api = serve({ queries: { revenue }, }); // ✅ Register the route - required for HTTP access! api.route('/revenue', api.queries.revenue, { method: 'POST' });
2. Start the server:
npx hypequery dev src/analytics/queries.ts # Server running at http://localhost:4000
hypequery devspins up the same HTTP server yourapi.handleruses, so once you register routes (step 1) every endpoint is reachable without any extra wiring. In production you can do the equivalent by callingawait api.start({ port }), or by embeddingapi.handlerinside your own framework/server if you don't want to rely on the CLI entry point.
3. Call your API:
curl -X POST http://localhost:4000/revenue # {"total": 125000, "count": 450}
That's it! Your query is now available as an HTTP endpoint with auto-generated OpenAPI docs at http://localhost:4000/docs.
Deployment Models
Embedded in Framework (Recommended for Web Apps)
Integrate hypequery directly into your web framework. Routes run on the same port as your application.
Supported frameworks:
- Next.js (Vercel adapter)
- Express
- Hono
- Any framework with standard Request/Response handlers
Example: Next.js
// app/api/hypequery/[...hq]/route.ts import { api } from '@/analytics/queries'; import { createFetchHandler } from '@hypequery/serve'; export const runtime = 'nodejs'; const handler = createFetchHandler(api.handler); export const GET = handler; export const POST = handler; export const OPTIONS = handler;
Example: Express
Use the Node adapter to mount hypequery alongside your existing routes:
// server.ts import express from 'express'; import { createNodeHandler } from '@hypequery/serve'; import { api } from './analytics/queries'; const app = express(); // Mount hypequery at /api/analytics app.use('/api/analytics', createNodeHandler(api.handler)); app.listen(3000);
Standalone Server
Run a dedicated hypequery server on its own port:
// src/analytics/server.ts import { api } from './queries'; await api.start({ port: 4000 });
api.start() starts the default Node server and returns a { stop() } handle for shutdown. If you need custom app routes, mount api.handler inside your own Express, Hono, or Next.js server instead of expecting an app object from start().
Or use the CLI:
# Development npx hypequery dev src/analytics/queries.ts --port 4000 # Production npx hypequery serve src/analytics/queries.ts --port 8080
Edge/Fetch Runtimes
Deploy to edge platforms using the standard Fetch API:
// Cloudflare Worker import { api } from './analytics/queries'; import { createFetchHandler } from '@hypequery/serve'; const handler = createFetchHandler(api.handler); export default { fetch(request: Request) { return handler(request); }, }; // Vercel Edge Function import { api } from './analytics/queries'; import { createFetchHandler } from '@hypequery/serve'; const handler = createFetchHandler(api.handler); export default function handler(request: Request) { return handler(request); }
OpenAPI Documentation
Auto-generated OpenAPI specs are available at /openapi.json:
curl http://localhost:4000/openapi.json
Customize the generated OpenAPI document through serve({ openapi: ... }):
const api = serve({ queries: { revenue }, openapi: { title: 'My Analytics API', version: '2.0.0', servers: [ { url: 'https://api.example.com', description: 'Production' }, ], }, });
Documentation UI
Serve interactive API documentation from the built-in /docs route, or customize the generated page with serve({ docs: ... }):
const api = serve({ queries: { revenue }, docs: { title: 'My API Docs', subtitle: 'Analytics runtime', darkMode: true, }, });
The runtime will expose that UI at /docs automatically once routes are registered.
If you want to host the docs HTML yourself, use the exported helper:
import { buildDocsHtml } from '@hypequery/serve'; app.get('/docs', (req, res) => { res.send(buildDocsHtml('/openapi.json', { title: 'My API Docs', subtitle: 'Analytics runtime', darkMode: true, })); });
Custom Routes
Register individual queries with custom paths and methods:
import { api } from './analytics/queries'; // Register with custom path api.route('/analytics/revenue', api.queries.revenue, { method: 'POST' }); // Register as GET api.route('/health', api.queries.healthCheck, { method: 'GET' }); // Use query metadata from definition api.route('/weekly', api.queries.weeklyRevenue);