recode-fa23

Servers

Serving Static Files

The websites we have built so far have only dealt with the front end, client-side code that executes in the browser. Working with API’s would be the only exception, but we are still only consuming the external data, not providing it ourselves. In this way, these sites are considered to be static - the client requests the HTML page and it is sent by the server. This request may also include CSS or Javascript files, images, video, etc. and the experience is sort of all contained there in the browser.

To run a server that mimics the behavior of the VS Code Live Server extension, we can use so-called “middleware” in Express. The code would look like this:

const express = require('express')
// using 'app' is the typical way in express.js
const app = express()
// a common development port
const port = 3000

// 'use' the static middleware and give it a path
// 'public' refers to which part of the server is exposed to the web
app.use(express.static('public'))

// listen means the server is running
app.listen(port, () => console.log(`Server listening here: http://localhost:${port}!`))

But what if there is additional data that needs to be updated on the page? The user can of course refresh the page manually, but in the case of real-time communication like chat or a news feed, this doesn’t make for a pleasant user experience. In order to manage sending updated data in real-time, or as close to real-time as the network will allow, you need to manage the backend as well as the front end.

To go further in mimicking our VS Code Live Server, but for the backend, we can use nodemon to get the auto-refresh behavior each time we make a change. Read more here.

Taking Requests

We have worked some with how API’s can give us external data, but what if you wanted to write your own API? Well, that is where servers come in. Servers allow us to control not only the static files that are sent to the client (our front-end files), but all kinds of other things.

Basic HTTP Requests

There are a number of basic types of HTTP requests, but the main two we’ll focus on are:

That’s because they comprise most of what you’ll need to do: GET/download data and POST/upload data.

Let’s first look at a simple ‘hello world’ server example where we will use the GET method. GET is the default method for all regular web browsing that you do.

For this, we will be using Express.js which is a very robust server library. Express is capable of doing the most simple tasks, all the way up to writing very robust API’s. It uses the app object and parlance for most of it’s functionality. The server will “listen” for HTTP requests, either from a browser or terminal or other interface, and return some data based on the server configuration.

For now, we’ll just listen for a GET request and simply respond with, “hello world”:

const express = require('express')
const app = express()
const port = 3000

// the first argument is called the 'route'
// and a callback to handle the request
app.get("/", () => res.send("hello world"))

// listen means the server is running
app.listen(port, () => console.log(`Server listening here: http://localhost:${port}!`))

Now when we point our browser to http://localhost:3000, we should see ‘hello world’ in our browser window.

Reading recommendation: The excellent book Express In Action can show you how to build robust and secure server applications that manage user data, databases, and more.

Under lock and key

Servers allow us a level of security and obfuscation that front-end code alone does not. After all, your bank account information is availalbe on the web, but only to a select few, namely (and only) you (so we hope 😈). This is accomplished with passwords of course. And since servers store those passwords out of sight, users can rest assured that their information is secure.

We can demonstrate this behavior by putting our website behind a simple password system using Express.js’s middleware.

Check out this example here.

Status Report

We’re all familiar with the 404 NOT FOUND error, but did you know there are a number of response status codes?

From MDN:

HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes:

1) Informational responses (100 – 199)
2) Successful responses (200 – 299)
3) Redirection messages (300 – 399)
4) Client error responses (400 – 499)
5) Server error responses (500 – 599)

``````