h3
Version:
163 lines (100 loc) • 6.31 kB
Markdown
> H3 automatically converts any returned value into a web response.
Values returned from [Event Handlers](/guide/basics/handler) are automatically converted to a web [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) by H3.
**Example:** Simple event handler function.
```js
const handler = defineHandler((event) => ({ hello: "world" }));
```
H3 smartly converts handler into:
```js
const handler = (event) =>
new Response(JSON.stringify({ hello: "world" }), {
headers: {
"content-type": "application/json;charset=UTF-8",
},
});
```
> [!TIP]
> 🚀 H3 uses srvx `FastResponse` internally to optimize performances in Node.js runtime.
If the returned value from event handler is a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or from an [async function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function), H3 will wait for it to resolve before sending the response.
If an error is thrown, H3 automatically handles it with error handler.
<read-more></read-more>
Before returning a response in main handler, you can prepare response headers and status using [`event.res`](/guide/api/h3event
```js
defineHandler((event) => {
event.res.status = 200;
event.res.statusText = "OK";
event.res.headers.set("Content-Type", "text/html");
return "<h1>Hello, World</h1>";
});
```
> [!NOTE]
> If a full [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response) value is returned, prepared status is discarded and headers will be merged/overriden. For performance reasons, it is best to only set headers only from final Response in this case.
> [!NOTE]
> If an Error happens, prepared status and headers will be discarded. The recommended way to include headers in error responses is via `new HTTPError({ headers })`. As a last resort for headers that need to be set implicitly before the error is known (e.g., CORS), you can use `event.res.errHeaders` — these will be merged into error responses automatically.
## Response Types
H3 smartly converts JavaScript values into web [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response).
### JSON Serializable Value
Returning a [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) serializable value (**object**, **array**, **number** or **boolean**), it will be stringified using [JSON.stringify()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) and sent with default `application/json` content-type.
**Example:**
```ts
app.get("/", (event) => ({ hello: "world" }));
```
> [!TIP]
> Returned objects with `.toJSON()` property can customize serialization behavior. Check [MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) for more info.
Returning a string value, sends it as plain text body.
> [!NOTE]
> If not setting `content-type` header, it can default to `text/plain;charset=UTF-8`.
**Example:** Send HTML response.
```ts
app.get("/", (event) => {
event.res.headers.set("Content-Type", "text/html;charset=UTF-8");
return "<h1>hello world</h1>";
});
```
You can also use `html` utility as shortcut.
```js
import { html } from "h3";
app.get("/", () => html("<h1>hello world</h1>"));
```
Returning a web [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response/Response), sends-it as final reponse.
**Example:**
```ts
app.get("/", (event) => new Response("Hello, world!", { headers: { "x-powered-by": "H3" } }));
```
> [!IMPORTANT]
> When sending a `Response`, any [prepared headers](
Returning a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) or Node.js [`Readable`](https://nodejs.org/api/stream.html#readable-streams) sends it as stream.
Send binary [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) or node [Buffer](https://nodejs.org/api/buffer.html#buffer).
`content-length` header will be automatically set.
Send a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) as stream.
`Content-type` and `Content-Length` headers will be automatically set.
Send a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) as stream.
`Content-type`, `Content-Length` and `Content-Disposition` headers will be automatically set.
Some less commonly possible values for response types.
Sends a response with empty body.
> [!TIP]
> If there is no `return` statement in event handler, it is same as `return undefined`.
Retuning an [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) instance will send it.
> [!IMPORTANT]
> It is better to `throw` errors instead of returning them. This allows proper propagation from any nested utility.
<read-more></read-more>
Value will be sent as stringified version of BigInt number.
> [!NOTE]
> Returning a JSON object, does not allows BigInt serialization. You need to implement `.toJSON`. Check [MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) for more info.
**Returning Symbol or Function has undetermined behavior.** Currently, H3 sends a string-like representation of unknown Symbols and Functions but this behavior might be changed to throw an error in the future versions.
There are some internal known Symbols H3 internally uses:
- `Symbol.for("h3.notFound")`: Indicate no route is found to throw a 404 error.
- `Symbol.for("h3.handled")`: Indicate request is somehow handled and H3 should not continue (Node.js specific).