Is there a way to create a http server based on Fetch API? (Request, Response, Headers, ...)
Details
I want to create basic HTTP server with Node.js. I also want to declare request handler based on Fetch API like this:
import { serve } from 'node:http/nonexistent';
async function handler(request) {
await doSomething();
return new Response('{}', { headers: { 'content-type': 'application/json' } });
}
serve(handler, { port: 1234 });
Are there any built-in packages to achieve this?
If not, how to properly use the http package and convert IncomingMessage to Request and use the Response to send response in the handler of createServer function?
Node.js version
18+
Example code
Here is my naive implementation of the serve function. I have several quetions about it:
- will such an implementation work fast enough? Or there are clear indicators of speed drawdown
- can anyone suggest what use cases i'm missing (other than error handling)?
import { createServer } from 'node:http';
import { Readable } from 'node:stream';
export function serve({ port, fetch }) {
const base = `http://localhost:${port}`;
const server = createServer(async (req, res) => {
const response = await fetch(
new Request(new URL(req.url ?? '', base), {
// body: ???
headers: toHeaders(req.headers),
}),
);
res.writeHead(response.status, [...response.headers]);
if (response.body) {
Readable.fromWeb(response.body).pipe(res);
} else {
res.end();
}
});
server.listen(port);
}
function toHeaders(headers) {
return Object.entries(headers).reduce((acc, [name, value]) => {
if (typeof value === 'string') {
acc.push([name, value]);
} else if (Array.isArray(value)) {
value.forEach(item => acc.push([name, item]));
}
return acc;
}, []);
}
Operating system
macos
Scope
runtime
Module and version
Not applicable.
Can you show how the request looks like
@preveen-stack not quite understand what the request means?
If not, how to properly use the http package and convert IncomingMessage to Request and use the Response to send response in the handler of createServer function? the "Request" you mentioned in the issue
@preveen-stack global Node.js constructors Request and Response from Fetch API:
new Request('http://site.com', { method: 'POST' });
new Response('Not found', { status: 404 });
This seems like a pretty nice thing for Node.js to have. I'm trying to write these conversion methods myself but it's easy to mis something 😅 could this be a rework of createServer
Stumbled upon this while looking for solutions on how to use itty-router with node.js. Found this so far https://www.npmjs.com/package/@whatwg-node/server ... but it says it ponyfills, which is better than polyfilling, but it still does too much magic for my liking
It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.
@bra1nDump @whatwg-node/server is great, thanks
But it looks like a little tricky solution and i dont think this is get great performance
It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.
Are there any plans to add builtin utilities for creating an HTTP server on Fetch API in Node.js?
You can use expressjs to create a fetch api.
Creating express project
- Create a directory for your project
mkdir my-express-app
cd my-express-app
- Install expressjs
npm install express
- Create your app file. For example,
app.js
vim app.js
- In the
app.jsfile, create your api
const express = require('express'); // import express
const app = express(); // create an express app
const PORT = 3000; // specify a port for the app to listen to
// Code your api here. For example:
app.get("/", (req, res) => {
res.status(200).send("This is an example response.");
}); // replaceable
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
}); // this is required
- Save the file and run it with
node
node app.js
I'm closing this issue due to inactivity. At the current time, the only comments resolving the stalebot weren't relevant to resolving this issue, so I'll assume this is still stale.
To answer the question, no, there is not currently a way to write a server via the Fetch API, although you can always implement one :-).
Is this still not even under consideration? Nowadays, pretty much every JS-runtime except Node supports this: see https://blog.val.town/blog/the-api-we-forgot-to-name/ or https://marvinh.dev/blog/modern-way-to-write-javascript-servers/