h3 icon indicating copy to clipboard operation
h3 copied to clipboard

Migrating to Events API

Open pi0 opened this issue 2 years ago • 7 comments

h3 was born with the idea of being a platform-agnostic server framework for all JavaScript environments and backward compatibility with legacy server middleware format for Node.js and Express compatibility.

Initially, we started with the most backward-compatible format (req, res) and improved it by async support async (req, res) and also directly returning a response for a pleasant experience with (req, res) => 'Hello World' format.

unjs/unenv provides a createCall and mocks of Node.js HTTP built-ins. Thanks to this mocking framework, h3 is able to work nicely on almost any serverless or Worker platform.

However, this kind of setup keeps h3 to be away from natively supporting non Node.js environments with the cost of unenv overhead for any code not using Node.js.

Additionally, (req, res) format is not even suitable to extend h3 supporting Node.js features like http2 without compatibility API and ws support.

Migration to (event) format will be progressive and backward compatibility wherever necessary however we potentially have to introduce breaking changes as semver-minor until reaching [email protected].

Progress

  • [x] opt-in using event format using defineEventHandler (#74)
  • [x] use Event api with utils with compatibility layer (https://github.com/unjs/h3/pull/75)
  • [x] Event class (#81)
  • [x] Make node-js handlers opt-in and drop (req, res) implicit conversion (#178)
  • [x] Make event.req and event.res optional and adopt more of event native (#231)
  • [ ] Mock (with warning) for req, res (#472)
  • [ ] Migrate all leftover utils

pi0 avatar Mar 23 '22 11:03 pi0

Would this potentially add support for waitUntil in the fetch listener? So it could be utilized with Cloudflare Workers lifecycle for instance. (https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent/waitUntil)

PhaxeNor avatar May 19 '22 08:05 PhaxeNor

So what's the roadblock to get h3 (and Nuxt 3, as a result) to serve files via http2 protocol?

nathanchase avatar Dec 11 '22 04:12 nathanchase

I manually implemented something like this to play with Request/Response compatible libraries :

const getRequestFromEvent = async (event: H3Event) => {
  const url = new URL(getRequestURL(event))
  const method = getMethod(event)
  const body = method === "POST" ? await readRawBody(event) : undefined
  return new Request(url, { headers: makeHeaders(getRequestHeaders(event)), method, body })
}

A much cleaner and robust version of these would be greatly appreciated.

Something like this ...

const sendResponse = (event: H3Event, response: Response): Response => {
//implement, maybe this doesn't need to return a Response
}

... might be useful too.

For reference hattip seems to share similar design goals with h3, but is using a different API based on standard Request/Response.

Hebilicious avatar Apr 27 '23 14:04 Hebilicious

Linking amazing PR: https://github.com/unjs/h3/pull/395 for reference

pi0 avatar Jun 20 '23 21:06 pi0

Hello,

Is there any estimated date for completing this functionality?

alimozdemir avatar Oct 03 '23 06:10 alimozdemir

If anyone is trying to get http2 to work I was able to get up and running with node-spdy.

Here's some example code:

import { readFileSync } from 'fs';
import { createApp, eventHandler, toNodeListener } from 'h3';
import spdy from 'spdy';

const app = createApp();
app.use(
    '/',
    eventHandler(() => {
        return 'Hello world';
    }),
);

const options: spdy.ServerOptions = {
    cert: readFileSync('./<path-to-certificate>'),
    key: readFileSync('./<path-to-key>'),
};

const server = spdy.createServer(options, toNodeListener(app));

server.listen(3000, () => console.log('Server running on localhost:3000'));

If you need unencrypted traffic, (which is what I needed to get this running on Google Cloud Run) then you set the server options like so:

const options: spdy.ServerOptions = {
    spdy: {
        plain: true,
    },
};

Anyway hopefully this saves someone else the hours of trial and error I just went through :sweat_smile:

joshmossas avatar Dec 02 '23 00:12 joshmossas

So when will we have http2 support on Nuxt 3. I am able to achieve http2 on my project by using node-spdy like joshmosas mention but this repository is not undergoing active development.

bao-tran-saltovn avatar Jan 09 '24 14:01 bao-tran-saltovn