vk98's picture
Initial backend deployment - Hono proxy + ColPali embedding API
5dfbe50
import { serve } from '@hono/node-server';
import { Hono } from 'hono';
import { compress } from 'hono/compress';
import { secureHeaders } from 'hono/secure-headers';
import { timeout } from 'hono/timeout';
import { config } from './config';
import { corsMiddleware } from './middleware/cors';
import { loggerMiddleware, requestIdMiddleware } from './middleware/logger';
import { rateLimitMiddleware } from './middleware/rateLimit';
import { api } from './routes/api';
import { backendApi } from './routes/backend-api';
import { healthApp } from './routes/health';
const app = new Hono();
// Global middleware
app.use('*', requestIdMiddleware);
app.use('*', loggerMiddleware);
app.use('*', corsMiddleware);
app.use('*', secureHeaders());
app.use('*', compress());
// Apply rate limiting to API routes only
app.use('/api/*', rateLimitMiddleware);
// Apply timeout to prevent hanging requests (30 seconds, except for SSE)
app.use('/api/*', async (c, next) => {
if (c.req.path === '/api/chat') {
// Skip timeout for SSE endpoints
await next();
} else {
return timeout(30000)(c, next);
}
});
// Mount routes - matching backend API structure at root level
app.route('/', backendApi);
// Also mount at /api for direct Next.js API access (optional)
app.route('/api', api);
// Health check
app.route('/health', healthApp);
// Root info endpoint
app.get('/info', (c) => {
return c.json({
name: 'ColPali Hono Proxy',
version: '1.0.0',
endpoints: {
// Backend-compatible endpoints (Python API format)
search: '/fetch_results',
fullImage: '/full_image',
suggestions: '/suggestions',
similarityMaps: '/get_sim_map',
chat: '/get-message',
// Direct API endpoints
apiSearch: '/api/colpali-search',
apiFullImage: '/api/full-image',
apiSuggestions: '/api/query-suggestions',
apiSimilarityMaps: '/api/similarity-maps',
apiChat: '/api/visual-rag-chat',
health: '/health',
},
});
});
// 404 handler
app.notFound((c) => {
return c.json({ error: 'Not found', path: c.req.path }, 404);
});
// Global error handler
app.onError((err, c) => {
console.error(`Error handling request ${c.req.path}:`, err);
if (err instanceof Error) {
if (err.message.includes('timeout')) {
return c.json({ error: 'Request timeout' }, 408);
}
}
return c.json(
{
error: 'Internal server error',
requestId: c.get('requestId'),
},
500
);
});
// Start server
const port = config.port;
console.log(`πŸš€ ColPali Hono Proxy starting...`);
console.log(`πŸ“ Backend URL: ${config.backendUrl}`);
console.log(`πŸ”’ CORS Origin: ${config.corsOrigin}`);
console.log(`πŸ’Ύ Cache: ${config.enableCache ? 'Enabled' : 'Disabled'}`);
console.log(`🚦 Rate Limit: ${config.rateLimit.max} requests per ${config.rateLimit.windowMs / 1000}s`);
serve({
fetch: app.fetch,
port,
}, (info) => {
console.log(`βœ… Server running on http://localhost:${info.port}`);
});