UNPKG

query-2jz

Version:

Query-2jz: A GraphQL alternative with faster performance and simpler use

158 lines (132 loc) 3.76 kB
import { Server, Request, ResponseToolkit } from '@hapi/hapi'; import { Qryn, QrynConfig, QrynModel } from '../index'; /** * Hapi Adapter for Qryn */ export class QrynHapiAdapter { private qryn: Qryn; constructor(config: QrynConfig, models: QrynModel[] = []) { this.qryn = new Qryn(config, models); } /** * Initialize the adapter */ async initialize(): Promise<void> { await this.qryn.initialize(); } /** * Get Qryn instance */ getQryn(): Qryn { return this.qryn; } /** * Register Hapi routes */ async register(server: Server): Promise<void> { // Health check server.route({ method: 'GET', path: '/health', handler: async (request: Request, h: ResponseToolkit) => { const stats = this.qryn.getStats(); return { status: 'healthy', timestamp: new Date().toISOString(), ...stats }; } }); // Query endpoint server.route({ method: 'GET', path: '/api/qryn/{model}', handler: async (request: Request, h: ResponseToolkit) => { const model = request.params.model; const query = this.parseQueryParams(request.query); const result = await this.qryn.query(query, model); const response = h.response(result); if (result.meta?.etag) { response.header('ETag', result.meta.etag); } if (result.meta?.lastModified) { response.header('Last-Modified', result.meta.lastModified); } response.header('Cache-Control', 'public, max-age=300'); return response; } }); // Mutation endpoint server.route({ method: 'POST', path: '/api/qryn/{model}', handler: async (request: Request, h: ResponseToolkit) => { const model = request.params.model; const mutation = request.payload as any; if (!mutation.operation) { return h.response({ error: 'Invalid mutation', message: 'Operation is required' }).code(400); } const result = await this.qryn.mutate(mutation, model); const response = h.response(result); response.header('Cache-Control', 'no-cache'); return response; } }); // Statistics endpoint server.route({ method: 'GET', path: '/api/qryn/stats', handler: async (request: Request, h: ResponseToolkit) => { return this.qryn.getStats(); } }); } private parseQueryParams(queryParams: any): any { const query: any = {}; if (queryParams.select) { try { query.select = JSON.parse(queryParams.select); } catch { query.select = {}; } } if (queryParams.where) { try { query.where = JSON.parse(queryParams.where); } catch { query.where = {}; } } if (queryParams.orderBy) { try { query.orderBy = JSON.parse(queryParams.orderBy); } catch { query.orderBy = {}; } } if (queryParams.limit) { query.limit = parseInt(queryParams.limit); } if (queryParams.offset) { query.offset = parseInt(queryParams.offset); } if (queryParams.live === 'true') { query.live = true; } return query; } } /** * Hapi plugin factory */ export function createQrynPlugin(config: QrynConfig, models: QrynModel[] = []) { const adapter = new QrynHapiAdapter(config, models); return { adapter, plugin: adapter.register.bind(adapter), initialize: () => adapter.initialize() }; }