Skip to content

Is there a way to create a http server based on Fetch API? (Request, Response, Headers, ...) #4174

@krutoo

Description

@krutoo

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions