Elide обслуговує HTTP через fetch-обробник або через node:http; на цій сторінці один і той самий сервіс побудовано
обома способами.
Два способи обслуговування
| Fetch-обробник | node:http | |
|---|---|---|
| Точка входу | export default { fetch } або Elide.serve({ fetch }) | http. |
| Запит і відповідь | Вебоб’єкти Request, Response | IncomingMessage, ServerResponse |
| HTTPS і HTTP/2 | Параметри cert і key | Недоступно |
--contexts | Так | Ні; друга копія завершується помилкою EADDRINUSE |
// server.ts
export default {
port: Number(process.env.PORT ?? 3000),
fetch(request: Request): Response {
return new Response("hello\n");
},
};// node-server.ts
import { createServer } from "node:http";
const port = Number(process.env.PORT ?? 3000);
createServer((req, res) => {
res.writeHead(200, { "content-type": "text/plain" });
res.end("hello\n");
}).listen(port, "127.0.0.1");elide run server.ts
curl -i http://127.0.0.1:3000/HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
content-length: 6
server: elide
date: Sat, 10 Oct 2026 00:18:12 GMT
helloelide run node-server.ts відповідає на той самий запит із Transfer-Encoding: chunked і Connection: keep-alive.
До якої адреси прив’язується кожен варіант, якщо адресу не вказано:
| Сервер | Адреса за замовчуванням |
|---|---|
export default { fetch } під elide run | 127.0.0.1:8080 |
export default { fetch } під elide serve / elide dev | 127.0.0.1:8080 / 127.0.0.1:3000; --host і --port її перевизначають |
Elide. | 0.0.0.0 на port |
Маршрути, JSON і потокова передача
URLPattern, Request.json(), Response.json() і тіла ReadableStream доступні глобально. Цей сервер має API,
потокову відповідь і статичні файли з public/:
// app.ts
import { readFile } from "node:fs/promises";
import { extname, join, normalize } from "node:path";
const users = new URLPattern({ pathname: "/api/users/:id" });
const types: Record<string, string> = {
".html": "text/html; charset=utf-8",
".css": "text/css",
".js": "text/javascript",
};
async function api(request: Request): Promise<Response | null> {
const url = new URL(request.url);
const match = users.exec(url);
if (match && request.method === "GET") {
return Response.json({ id: match.pathname.groups.id });
}
if (url.pathname === "/api/users" && request.method === "POST") {
const body = await request.json();
return Response.json({ created: body.name }, { status: 201 });
}
if (url.pathname === "/api/ticks") {
let n = 0;
const stream = new ReadableStream({
async pull(controller) {
controller.enqueue(new TextEncoder().encode(`tick ${++n}\n`));
await new Promise((r) => setTimeout(r, 200));
if (n === 3) controller.close();
},
});
return new Response(stream, { headers: { "content-type": "text/plain" } });
}
return null;
}
async function file(pathname: string): Promise<Response> {
const path = join("public", normalize(pathname === "/" ? "/index.html" : pathname));
try {
const body = await readFile(path);
return new Response(body, { headers: { "content-type": types[extname(path)] ?? "application/octet-stream" } });
} catch {
return new Response("not found\n", { status: 404 });
}
}
export default {
port: Number(process.env.PORT ?? 3000),
async fetch(request: Request): Promise<Response> {
return (await api(request)) ?? file(new URL(request.url).pathname);
},
};elide run app.ts
curl http://127.0.0.1:3000/api/users/42
curl -X POST -H 'content-type: application/json' -d '{"name":"ada"}' http://127.0.0.1:3000/api/users
curl -N http://127.0.0.1:3000/api/ticks{"id":"42"}
{"created":"ada"}
tick 1
tick 2
tick 3POST відповідає 201 Created. Три тіки надходять з інтервалом 200 мс. / повертає public/index.html, а відсутній
файл — 404.
Той самий API на node:http читає тіло через node:stream/consumers і передає потік через res.write:
// node-app.ts
import { createServer } from "node:http";
import { text } from "node:stream/consumers";
createServer(async (req, res) => {
if (req.method === "POST" && req.url === "/api/users") {
const body = JSON.parse(await text(req));
res.writeHead(201, { "content-type": "application/json" });
res.end(JSON.stringify({ created: body.name }));
return;
}
if (req.url === "/api/ticks") {
res.writeHead(200, { "content-type": "text/plain" });
for (let n = 1; n <= 3; n++) {
res.write(`tick ${n}\n`);
await new Promise((r) => setTimeout(r, 200));
}
res.end();
return;
}
res.writeHead(404).end();
}).listen(Number(process.env.PORT ?? 3000), "127.0.0.1");Щоб роздавати лише файли, використовуйте elide serve ./public; див. Сервер розробки.
Помилки
Fetch-обробник, який кидає виняток або повертає відхилений проміс, відповідає 500 Internal Server Error і продовжує
обслуговувати запити. Помилка не виводиться, тож перехоплюйте й записуйте її самі:
curl -i -d 'not json' http://127.0.0.1:3000/api/usersHTTP/1.1 500 Internal Server Error
Content-Type: text/plain; charset=utf-8
content-length: 21
server: elide
date: Sat, 10 Oct 2026 00:34:28 GMT
Internal Server ErrorTLS
Передайте рядки PEM як cert і key в Elide.serve або як властивості експортованого об’єкта. Ключ має бути
у форматі PKCS#8 без шифрування (BEGIN PRIVATE KEY). Клієнти, які пропонують HTTP/2, отримують його.
// tls.ts
import { readFileSync } from "node:fs";
Elide.serve({
port: Number(process.env.PORT ?? 8443),
cert: readFileSync("cert.pem", "utf8"),
key: readFileSync("key.pem", "utf8"),
fetch(request) {
return new Response("hello over tls\n");
},
});elide run tls.ts
curl -i --cacert cert.pem https://localhost:8443/HTTP/2 200
content-type: text/plain;charset=UTF-8
content-length: 15
server: elide
date: Sat, 10 Oct 2026 00:18:52 GMT
hello over tlselide serve і elide dev не мають прапорців TLS, а elide.pkl не має налаштувань TLS. https.createServer кидає:
Error: HTTPS server is not supported in this runtime (no host TLS listener); use http.createServer behind a TLS terminator, or https client APIs.Кілька контекстів
--contexts=N запускає N копій застосунку з fetch-обробником на одному порту, у Linux. Кожна копія має власний стан
модулів:
// counter.ts
let count = 0;
export default {
fetch(): Response {
count += 1;
return new Response(`${count}\n`);
},
};elide serve --no-tui --contexts=4 counter.ts
for i in 1 2 3 4 5 6 7 8; do curl -s http://127.0.0.1:8080/; done1
1
2
2
3
4
1
2Зберігайте спільний стан у базі даних або іншому сервісі. --contexts=auto визначає кількість за ядрами CPU;
engine.contexts в elide.pkl задає її для проєкту (Контексти рушія).
Фреймворки
Встановіть їх командою elide install --ecosystems=npm.
| Фреймворк | Стан |
|---|---|
| Hono | Працює: export default { fetch: app. або export default app. |
| Express 5 | Маршрутизація, res.json, express.raw() і ручне читання req працюють. express.json() і express.text() зупиняють процес із TypeError: Buffer.. |
| Fastify 5 | Помилка під час імпорту: Error: No such built-in module: node:http2. |
// hono-app.ts
import { Hono } from "hono";
const app = new Hono();
app.get("/users/:id", (c) => c.json({ id: c.req.param("id") }));
app.post("/users", async (c) => c.json({ created: (await c.req.json()).name }, 201));
export default {
port: Number(process.env.PORT ?? 3000),
fetch: app.fetch,
};Приклади
- HTTP-обробник
- Маршрути з URLPattern
- Локальний сервер і fetch
- Server-sent events
- Обмеження запитів
- Сервер із кількома контекстами