magne4000 / universal-middleware

Write middleware once, target Hono, Cloudflare, Express, and more
https://universal-middleware.dev/
MIT License
28 stars 2 forks source link

feat: self-subscribing universal middlewares #22

Closed brillout closed 3 months ago

brillout commented 3 months ago

Server framework extensions:

  • vike-express
  • vike-hono
  • vike-fastify
  • ...

These would automatically integrate universal middlewares (by creating a new setting +middleware). For example, adding Telefunc to an existing app will be done simply by adding vike-telefunc: the Telefunc middleware is then automatically added

How could Telefunc's universal middleware define its URL route? Maybe we'll need https://github.com/magne4000/universal-middleware/discussions/4 at some point :thinking:

magne4000 commented 3 months ago

I was going to say that it should not declare its route, to keep things simple. A package using universal-middleware could also export its "suggested" route like this:

import telefuncHandler from "telefunc/middleware/hono";
import telefuncRoute from "telefunc/middleware/hono-route";

...
app.post(telefuncRoute, telefuncHandler());

But this route will:

  1. not necessarily be compatible with all servers. For instance, the fail-over handler route in Hono is "*", but in h3 is "/**"
  2. not be tied to what the user could have possibly overridden through the handler configuration

Let me explain this second point:

const handler = telefuncHandler({
  route: "/api/telefunc"
});

// We can't use `telefuncRoute` anymore
app.post("/api/telefunc", handler);

Those two points non problems if packages leveraging universal-middleware are used directly by the user, as one can override the routes manually.

But even for a package such as vike-telefunc, either the default route will be applied by default, or non-default if the user overrides them.

So the only issue remaining is the first point. How to represent a universal route, and how to convert such route to adapters compatible ones.

We can create a @universal-middleware/tools package that would export helpers like toHonoRoute(route: string): string, that can then be used by vike-telefunc or alike.

brillout commented 3 months ago

Actually, how about we make all +middleware be catch-all middlewares that are self-responsible for routing?

Telefunc example:

// node_modules/vike-telefunc/dist/integration/+middleware.js

export { middleware }

import { telefunc, config, provideTelefuncContext } from 'telefunc';

async function middleware(request, ctx) {
  // Needs to be called not only for Telefunc requests, but also for page
  // requests (in order to support SSR).
  provideTelefuncContext(ctx)

  if (request.url === config.telefuncUrl || '/_telefunc') {
    const response = await telefunc({
      url: request.url,
      method: request.method,
      body: await request.text()
    })
    return new Response(response.body, {
      headers: new Headers({ contentType: response.contentType }),
      status: response.statusCode
    })
  }
}
magne4000 commented 3 months ago

It does work indeed :)

brillout commented 3 months ago

Another pro: we can implement it in Vike land including the magic number, so I guess we can close this.

Thanks for the conversation :)