h3
Version:
166 lines (107 loc) • 4.12 kB
Markdown
# Event Handlers
> An event handler is a function that receives an H3Event and returns a response.
You can define typed event handlers using `defineHandler`.
```js
import { H3, defineHandler } from "h3";
const app = new H3();
const handler = defineHandler((event) => "Response");
app.get("/", handler);
```
> [!NOTE]
> Using `defineHandler` is optional.
> You can instead, simply use a function that accepts an [`H3Event`](/guide/api/h3event) and returns a response.
The callback function can be sync or async:
```js
defineHandler(async (event) => "Response");
```
## Object Syntax
### middleware
You can optionally register some [middleware](/guide/basics/middleware) to run with event handler to intercept request, response or errors.
```js
import { basicAuth } from "h3";
defineHandler({
middleware: [basicAuth({ password: "test" })],
handler: (event) => "Hi!",
});
```
<read-more></read-more>
<read-more></read-more>
### meta
You can define optional route meta attached to handlers, and access them from any other middleware.
```js
import { H3, defineHandler } from "h3";
const app = new H3();
app.use((event) => {
console.log(event.context.matchedRoute?.meta); // { tag: "admin" }
});
app.get("/admin/**", defineHandler({
meta: { tag: "admin" },
handler: (event) => "Hi!",
})
```
<read-more>
It is also possible to add route meta when registering them to app instance.
</read-more>
## Handler `.fetch`
Event handlers defined with `defineHandler`, can act as a web handler without even using [H3](/guide/api/h3) class.
```js
const handler = defineHandler(async (event) => `Request: ${event.req.url}`);
const response = await handler.fetch("http://localhost/");
console.log(response, await response.text());
```
## Lazy Handlers
You can define lazy event handlers using `defineLazyEventHandler`. This allow you to define some one-time logic that will be executed only once when the first request matching the route is received.
A lazy event handler must return an event handler.
```js
import { defineLazyEventHandler } from "h3";
defineLazyEventHandler(async () => {
await initSomething(); // Will be executed only once
return (event) => {
return "Response";
};
});
```
This is useful to define some one-time logic such as configuration, class initialization, heavy computation, etc.
Another use-case is lazy loading route chunks:
```js [app.mjs]
import { H3, defineLazyEventHandler } from "h3";
const app = new H3();
app.all(
"/route",
defineLazyEventHandler(() => import("./route.mjs").then((mod) => mod.default)),
);
```
```js [route.mjs]
import { defineHandler } from "h3";
export default defineHandler((event) => "Hello!");
```
## Converting to Handler
There are situations that you might want to convert an event handler or utility made for Node.js or another framework to H3.
There are built-in utils to do this.
### From Web Handlers
Request handlers with [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) => [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) signuture can be converted into H3 event handlers using `fromWebHandler` utility or [H3.mount](/guide/api/h3#h3mount).
```js
import { H3, fromWebHandler } from "h3";
export const app = new H3();
const webHandler = (request) => new Response("👋 Hello!");
// Using fromWebHandler utiliy
app.all("/web", fromWebHandler(webHandler));
// Using simple wrapper
app.all("/web", (event) => webHandler(event.req));
// Using app.mount
app.mount("/web", webHandler);
```
### From Node.js Handlers
If you have a legacy request handler with `(req, res) => {}` syntax made for Node.js, you can use `fromNodeHandler` to convert it to an h3 event handler.
> [!IMPORTANT]
> Node.js event handlers can only run within Node.js server runtime!
```js
import { H3, fromNodeHandler } from "h3";
// Force using Node.js compatibility (also works with Bun and Deno)
import { serve } from "h3/node";
export const app = new H3();
const nodeHandler = (req, res) => {
res.end("Node handlers work!");
};
app.get("/web", fromNodeHandler(nodeHandler));
```