Kodokon kodokon.com

Your first native HTTP server

You create a web server with Node's http module, respond to requests, and return JSON.

10 min · 3 questions

Open this lesson in Kodokon

A web server is a program that runs continuously and waits for requests: demands sent by a client (a browser, a mobile app, and so on). For every request, it returns a response. This dialogue follows the HTTP protocol, the common language of the web. Node includes a ready-to-use http module: nothing to install. One last notion: the port, a number that identifies a specific program on a machine, like an apartment number in a building. We'll use port 3000; as for localhost, it simply designates your own machine.

JAVASCRIPT
import http from "node:http";

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("Hello from my server!");
});

server.listen(3000, () => {
  console.log("Server at http://localhost:3000");
});
Save this code in server.js then run node server.js.

Let's break it down. http.createServer receives a function called on every request, with two parameters: req (the incoming request) and res (the response being built). res.statusCode = 200 sets the status code - 200 means "all good". res.setHeader adds a header, a piece of metadata about the response: here its format, plain text. res.end sends the response and closes it. Finally, server.listen(3000) puts the server listening on port 3000. Open http://localhost:3000 in your browser: your text appears. Notice that the program doesn't hand control back: it waits for requests. Stop it with Ctrl+C.

Modern servers rarely return plain text: they expose APIs that respond in JSON, that text format you already know, understood by every language. Two adjustments: the Content-Type header becomes application/json, and the JavaScript object is converted into text with JSON.stringify. Let's take the chance to react differently depending on req.url, the path requested by the client: this is the basis of routing.

JAVASCRIPT
import http from "node:http";

const server = http.createServer((req, res) => {
  res.setHeader("Content-Type", "application/json");

  if (req.url === "/api/message") {
    const body = { message: "Hello!", ok: true };
    res.statusCode = 200;
    res.end(JSON.stringify(body));
    return;
  }

  res.statusCode = 404;
  res.end(JSON.stringify({ error: "Not found" }));
});

server.listen(3000, () => {
  console.log("http://localhost:3000/api/message");
});
A known route responds 200 with a JSON object; any other path receives a 404.

The 404 status code means "not found": the requested path matches no known route. Note the return after the first response: it stops the code from continuing and sending a second response, which would cause an error. To test, open the address in the browser, or use curl, a command-line tool that sends HTTP requests and shows the response in the terminal.

BASH
curl http://localhost:3000/api/message
In a second terminal, while the server is running: the JSON response appears.

Knowledge check

Make sure you remember the key points of this lesson.

  1. What does server.listen(3000) do?
    • It puts the server listening for requests on port 3000
    • It sends a request to port 3000
    • It limits the server to 3000 simultaneous requests
    • It opens the browser on localhost:3000
  2. Which header do you send to indicate that the response is JSON?
    • Accept: application/json
    • Content-Type: application/json
    • Format: json
  3. Why pass the object through JSON.stringify before res.end?
    • To compress the response and save time
    • To check that the object contains no error
    • Because an HTTP response carries text, not a JavaScript object