Skip to content

Triplit server to export web standard Request / Response handler #313

@doeixd

Description

@doeixd

Hey there,

I'm working on a SolidStart project and had an idea that might make life easier for everyone. It would be awesome if the Triplit server could run as a route handler instead of booting up its own HTTP server. This change would let it plug right into any framework that uses the web standard request/response model—think SolidStart, Astro, H3, Nuxt, and the like.

Right now, Triplit uses Hono and starts its own server via serve. What if it instead exported its app.fetch handler? Then you could simply import that handler into your project’s route file and have it handle requests like any other endpoint. This approach is neat because:

  • Flexible Integration: It would work seamlessly with any framework that uses standard request/response objects. Whether you’re building on Astro, H3, Nuxt, or SolidStart, you’d have an easy way to integrate Triplit without running a separate server.
  • Simplified Deployment: If you're deploying to serverless or edge environments, having a single request handler is much simpler than managing a dedicated server.
  • Cleaner Codebase: It keeps your project’s routing and middleware more unified, letting you manage everything in one place.

Here’s a quick sketch of what this might look like:

  1. Refactor Triplit to export a request handler:
    Create a file like src/server/triplitHandler.ts where you initialize the Hono app and export the fetch function:

    // src/server/triplitHandler.ts
    import url from 'url';
    import * as Sentry from '@sentry/node';
    import path from 'path';
    import { createRequire } from 'module';
    import { createTriplitHonoServer } from './hono.js';
    import { createNodeWebSocket } from '@hono/node-ws';
    import { Hono } from 'hono';
    
    function initSentry() {
      if (process.env.SENTRY_DSN) {
        let packageDotJson;
        try {
          const require = createRequire(import.meta.url);
          const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
          packageDotJson = require(path.join(__dirname, '../package.json'));
        } catch {}
        Sentry.init({
          dsn: process.env.SENTRY_DSN,
          release: packageDotJson?.version ?? 'unknown',
        });
      }
    }
    
    function captureException(e: any) {
      if (Sentry.isInitialized() && e instanceof Error) {
        Sentry.captureException(e);
      }
    }
    
    // Initialize Sentry if needed.
    initSentry();
    
    // Create the Hono app and set up WebSocket handling.
    const app = new Hono();
    const { upgradeWebSocket } = createNodeWebSocket({ app });
    
    // Set up the Triplit Hono server on the app.
    await createTriplitHonoServer(
      {
        // your options here
      },
      upgradeWebSocket,
      captureException,
      app
    );
    
    // Export the Hono fetch function as the request handler.
    export async function handler(request: Request): Promise<Response> {
      return app.fetch(request);
    }
  2. Use it in your framework’s route:
    For instance, in a SolidStart project, you’d create a route like src/routes/api/triplit.ts and delegate requests to the handler:

    // src/routes/api/triplit.ts
    import type { RequestHandler } from 'solid-start';
    import { handler as triplitHandler } from '~/server/triplitHandler';
    
    export const GET: RequestHandler = async ({ request }) => {
      return triplitHandler(request);
    };
    
    // Optionally, handle other methods like POST:
    export const POST: RequestHandler = async ({ request }) => {
      return triplitHandler(request);
    };

This way, the Triplit server becomes a plug-and-play request handler that can easily fit into any project that relies on the standard web request/response flow. It makes integration smoother across various frameworks and opens up cool possibilities for serverless and edge deployments.

Thanks for considering this idea! Hope it makes sense and can help simplify things for everyone.

I'm happy to try and make a PR if the project is interested in the idea, if needed.

Cheers!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions