HTTP + OpenAPI
Expose hypequery metrics through HTTP handlers and autogenerated docs
HTTP + OpenAPI Delivery
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 { define, queries, query } = initServe({ context: () => ({ db }), }); export const api = define({ queries: queries({ revenue: query .describe('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]; }), }), }); // ✅ 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'; export const runtime = 'nodejs'; export const GET = api.handler; export const POST = api.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/adapters/node'; 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'; const server = await api.start({ port: 4000 }); // Optional: Add custom routes server.app.get('/health', (req, res) => res.json({ ok: true }));
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'; export default { fetch(request: Request) { return api.handler(request); }, }; // Vercel Edge Function import { api } from './analytics/queries'; export default function handler(request: Request) { return api.handler(request); }
OpenAPI Documentation
Auto-generated OpenAPI specs are available at /openapi.json:
curl http://localhost:4000/openapi.json
You can also generate the spec programmatically:
import { api } from './analytics/queries'; // Get the OpenAPI document const openApiDoc = api.openapi(); // Or build it with custom options const doc = await api.buildOpenApiDocument({ title: 'My Analytics API', version: '2.0.0', servers: [ { url: 'https://api.example.com', description: 'Production' }, ], });
Documentation UI
Serve interactive API documentation:
import { api } from './analytics/queries'; // Get the HTML for Redoc const docsHtml = await api.docsHtml(); // Or build it with custom options const html = await api.buildDocsHtml({ title: 'My API Docs', redocOptions: { theme: { colors: { primary: { main: '#FF6B6B' } } }, }, });
Then mount it wherever you want:
// Express example app.get('/docs', (req, res) => { res.send(await api.docsHtml()); });
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);