Hajime, the duck guy

Server-side scripting kata
On this page
Level: Essential

Basic NodeJS server

Creating a simple NodeJS server using the http module

The way of kata

Kata is an exercise for muscle memory. It's not intended to fill your brain with information but train your fingers to react. The information is there to give you the why, but your fingers need to learn the how.

The material on this page is presented in a specific order — from least specific to highly technical. You will learn the most by jumping in as soon as you have some idea of what you should do. Once you're done, read the rest of the material and check your solution.

All katas are designed to be doable without using 3rd party libraries (and, in fact, the point is to also learn how to do what these libraries do).

To make the best of katas, observe the following rules.

  • Don't rush.
  • When stuck, take a break and do something unrelated.
  • Do not copy/paste code. Always retype everything.
  • Do not use AI tools to generate code.
  • Try to do something that wasn't in the instructions, experiment.
  • Repeat the kata from time to time, even if you think you've got it.
  • You have mastered the kata once you are able to complete it without thinking too much.

Remember, the goal is not to get it done, but to get some practice.

Introduction

In this exercise, you will practice creating and starting a basic NodeJS server using nothing but the http module.

Skills you will acquire

  • Using the http module
  • Understanding the request-response cycle
  • Basic routing
  • Handling different methods
  • Making a HTML response
  • Using the curl to test the server

Objective

  • Create a server and launch it on port 4444
  • Returns a basic HTML page at the root path
  • Return a 404 HTMl page on any other path
  • Return a 405 HTML page on any method other than GET

Check your solution

  • Starting the server prints a message that the server is up on port 4444
  • Visiting localhost:4444 returns a simple HTML page
  • Visiting localhost:4444/something returns an error page (missing content)
  • Using curl to make a POST request will return an error page (wrong method)
  • The correct media type is returned for all responses

Keep in mind

The http.createServer() function creates a server object. This server is an event emitter. In this example, you only need to handle one event — 'request'. Since this is the most common scenario, the event handler is passed to http.creatServer() directly, instead of registering it afterwards using server.on(). (This example is given in the documentation, and can be used as a starting point. Remember to retype examples rather than copying and pasting them.)

I recommend sticking to the NodeJS convention of using req and res as event handler parameter names. This is a convention with a long history, and sticking to it will allow your eyes to get accustomed to a large body of examples floating around online.

When reading the NodeJS http module documentation, one thing that may be confusing is the terminology used to describe the request and response objects. In the documentation, these are called 'incoming message' and 'outgoing message' (http.IncomingMessage and http.OutgoingMessage, respectively), and map to the req and res objects shown in the examples.

For handling a request, the following information will come in handy:

  • Request path (the path portion of the URL)
  • Request method (a.k.a. verb)

The request path is not available directly. It is, instead, made available as req.url, which is a combination of the request path and search params. You can parse this using the URL constructor. (This constructor is the same one available in the browser.)

The HTTP protocol uses the so-called methods to differentiates between different types of request that can be made to the same URL. You will also encounter the term 'verb' referring to the same thing. These two terms are synonymous and can be used interchangeably. The methods can be GET, POST, PATCH, DELETE, and so on.

When using the curl tool, the POST request is made using the -d option:

curl -d http://localhost:4444/

The -d option can be followed by the request body, but in this exercise, you won't use any.

When making responses, you need, at the very least the following:

  • Response status code (defaults to 200)
  • The 'Content-Type' header
  • Response payload (content)

There are a few ways to set the status code and headers. I recommend using the following method:

res.statusCode = 200
res.setHeader('Some-Header', 'header value')

The 'Content-Type' header lets the browser (or some other user agent) determine what the type of the content is. These types are called media types (a.k.a., MIME type), and are standardized. You can discover the correct media type either by looking up the documentation or inspecting the Network tab in the developer tools on a some website.

To make a response, you will write the response payload into the response object. HTML is just string. There is no need to create HTML files on disk in order to implement this. Template literals in JavaScript support multi-line strings. When responding with HTML, you simply write the HTML string into the response object.

In it's essence, routing simply means that different code paths are selected based on the request path. Although there are many conventions about what paths should mean, ultimately it is up to the developer to establish a convention for the application — whether by using some of the established ones or inventing their own, whichever makes more sense for the application.

The routing can be as simple as a single switch statement, or an intricate system that maps paths to the filesystem. In this example, the requirements are rather trivial, so I recommend using a single if statement.

The routing may take methods into account or not. This is a matter of design for the particular application. In some cases, treating code paths as matching a particular path-method combination works better. In some cases, matching the path first, then branching based on the method works better. Sometimes, matching on the method, then branching by path is ideal. Given the requirements of this kata, you should determine which approach is better. If in doubt, try all three approaches.

The HTTP status code signify the status of the response. In this exercise, we have the following cases:

  • Everything was fine and the page was returned
  • The page was not found
  • The server does not support methods other than GET

Find the appropriate status codes for each condition.

Reading list

Want more?

Back to top