Week 13 - Systems

App Development lifecycle

Continuous integration (CI)

Continuous Delivery (CD)

Packaging and Docker

Docker setup

Building an API server

Deployments

Intro to Cloud

Using local LLMs

Appendix 1 yaml syntax

Appendix 2 Docker commands

Practice

Assignment

Core program

Using Express

So far, we have connected to external HTTP API servers to fetch data using HTTP GET, or to change data using methods like POST or PUT. In another words, we were the client. In this section, you will learn how to create your own HTTP API server. It can be easily done by using a popular npm package, express.

In this section, we will cover only the basics of Express to keep things simple. You are welcome to explore the framework further on your own.

<aside> 💭

We will not become backend developers after this chapter. The goal is to get familiar with how a backend works at a high level. Express offers many features we will not cover here.

</aside>

Creating a simple API server

Step 1: Initialization

In a new folder, create a new JavaScript app and install the Express package:

# Create a package.json file in our project
npm init -y

# Install express dependency
npm i express

Don’t forget to update your package.json and set the application type to module so you can use the import and export syntax:

image.png

<aside> 💭

The latest version of Express is 5. You may see many examples that use the older version 4, but most of them will also work with version 5. Use the latest version.

</aside>

Step 2: Initialization

Create a new file server.js with the following code:

import express from 'express';

// Initialize the Express application
const app = express();
const port = 3000;

// Define your first route to handle GET requests
app.get('/', (req, res) => {
  // On each request, send a HTTP 200 response with the message "Hello World!"
  res.status(200).send('Hello World!');
});

// Start the server and listen on the specified port
app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});

<aside> ⌨️

Hands on: Read the code above. Try to understand how it works.

</aside>

Step 3: Run and test

Start your server

node server.js

Unlike other Node.js applications, the server will stay running until stopped. As long as the server is running, it will respond to incoming HTTP request. Let’s test it

Test the server with your favorite method by sending GET request to http://localhost:3000

If you setup everything correctly, you should see a nice ‘Hello world!’ message.

<aside> 🎉

Well done! You have successfully created your very first API server!

</aside>

<aside> ⌨️

Hands on: Send a GET request to http://localhost:3000/hello . Did you receive a response back? If so, what the HTTP status code?

</aside>

Express routing in a nutshell

Our server from the previous example only handles one route: the root route (/). However, it will be handy to support multiple routes, such as /users or /login. You can do this with Express routing.

We will cover here only the basics of Express routing through examples.

Route syntax

Let’s look at the format of the route:

app.get('/users', (req, res) => {
  // Handle the request
});

The function app.get receives two parameters:

  1. A string (/users) represents the url pattern to match
  2. A callback function with two parameters: req (request) and res (response). This function is called for each new HTTP request that matches the string url pattern.

Your job as the API build is to implement the callback function, read the request object and send a proper response using the response object.

HTTP Methods

Handling specific HTTP methods:

app.get("/students", (req, res) => { ... });       // GET
app.post("/students", (req, res) => { ... });      // POST
app.put("/students/5", (req, res) => { ... });     // PUT
app.delete("/students/5", (req, res) => { ... });  // DELETE
app.all("/students/5", (req, res) => { ... });     // All HTTP methods

Matching specific URLs

app.get("/users", ...);                     //  /users
app.get("/users/report", ...);              // /users/report
app.get("/users/:id", ...);                 // /users/12, /users/abc, ... 
app.get("*", ...);                          // Match any url

Handling url parameters

// This will match:
// /trainees/123, /trainees/0, /trainees/abcd, ...
app.get("/trainees/:traineeId", (req, res) => {
  const id = req.params.traineeId;
  res.send(`Trainee ID: ${id}`);
});

Handling query string

// /trainees?traineeId=123
app.get("/trainees", (req, res) => {
  const id = req.query.traineeId;
  res.send(`Trainee ID: ${id}`);
});

Sending a status code

app.get('/', (req, res) => {
  res.status(200).send('Hello World!');
});

app.get('/abc', (req, res) => {
  res.status(404).send('Sorry, not found');
});

app.get('/xyz', (req, res) => {
  res.status(500).send('Server error!');
});

Sending different body types

// Text
app.get('/text', (req, res) => {
  res.send('Hello, this is a plain text response!');
});

// JSON
app.get('/json', (req, res) => {
  res.json({ message: 'Hello, this is a JSON response!' });
});

// HTML
app.get('/html', (req, res) => {
  res.set('Content-Type', 'text/html');
  res.send('<h1>Hello, this is an HTML response!</h1>');
});

// Sending any file
app.get('/file', (req, res) => {
  res.sendFile('/path/to/your/file.txt', (err) => {
    if (err) {
      res.status(500).send('Error sending file');
    }
  });
});

Handling HTTP request body

req.body will get you the request body that was sent. Not that you need an extra step to set it up with app.use(express.json());

import express from 'express';

const app = express();

app.use(express.json()); // for parsing application/json

app.post('/profile', (req, res, next) => {
  console.log(req.body);
  res.json(req.body);
});

Example: Simple todo list API

For a more complete example, take a look at the following simple todo list API:

https://github.com/HackYourFuture/Learning-Resources/tree/main/core-program/week-13/todo-api

<aside> ⌨️

Hands on: Open the simple todo list api with VSCode, inspect the code and run the application

</aside>

Extra resources


The HackYourFuture curriculum is licensed under CC BY-NC-SA 4.0 *https://hackyourfuture.net/*

CC BY-NC-SA 4.0 Icons

Built with ❤️ by the HackYourFuture community · Thank you, contributors

Found a mistake or have a suggestion? Let us know in the feedback form.