domi
domi

Reputation: 133

Deno serve imported from std/http/server.ts is not async iterable?

Here's the entirety of my .js file:

import { serve } from "https://deno.land/std/http/server.ts"

let server = serve({ port: 4000 })
for await (const req of server){
  console.log('literally anything')
}

I'm using entirely code which i've seen multiple other people run without issues, and i have myself ran similar for loops before on this same machine. I don't understand what i broke, or if i'm importing the wrong thing, i have no idea what the right thing is. I'm on Local Deno version 1.18.1, the path is the one i get from the deno.land site, and the error i get when i try deno run --allow-net on that code is:

error: Uncaught TypeError: server is not async iterable
for await (const req of server){ at file:///H:/proj/testapp/serveHTTP.js:4:25

Upvotes: 1

Views: 1610

Answers (1)

jsejcksn
jsejcksn

Reputation: 33748

The return type of serve used to be Server (which is async iterable) up until std version 0.106.0: here's a link to that version of serve. That's probably why you've seen examples using it that way.

Starting in version 0.107.0 of std, the signature of serve changed to accept a Handler instead (and return Promise<void>).

Here's a link to the documentation for the current version of serve (from [email protected]), and here's an example of how to use it:

so-70963882.ts:

import { serve } from "https://deno.land/[email protected]/http/server.ts";

function requestHandler (request: Request): Response {
  const data = {
    url: request.url,
    headers: Object.fromEntries([...request.headers].sort()),
  };

  console.log(data);
  const body: BodyInit = JSON.stringify(data, null, 2);
  const headers = new Headers([['content-type', 'application/json']]);
  const init: ResponseInit = {headers};
  return new Response(body, init);
}

const ac = new AbortController();
serve(requestHandler, { port: 4000, signal: ac.signal });

const responseText = await (await fetch('http://localhost:4000')).text();
console.log(responseText);
ac.abort();

In the console:

deno run --allow-net ./so-70963882.ts
{
  url: "http://localhost:4000/",
  headers: {
    accept: "*/*",
    "accept-encoding": "gzip, br",
    host: "localhost:4000",
    "user-agent": "Deno/1.18.1"
  }
}
{
  "url": "http://localhost:4000/",
  "headers": {
    "accept": "*/*",
    "accept-encoding": "gzip, br",
    "host": "localhost:4000",
    "user-agent": "Deno/1.18.1"
  }
}

You should always use versioned URLs — which are more likely to "be immutable" (provide idempotent responses) — for imported modules whenever possible.

Upvotes: 3

Related Questions