Minimal REST API Template using Express
Tags: javascript, node, beginners
Published: 2021-11-22 16:45:01

👋 Hello everybody! I recently helped a friend who is very new to web development get started with creating an express REST API for the mobile application they are creating. I figured I would share how I created the base template I drafted in case it can help anyone else!

### Overview ✨

At the end of this, you will have a very minimal template for scaling up your node/express application. Everything will be in JavaScript, however I encourage you to instead consider learning/using TypeScript for the enhanced safety benefits and developer experience. Since this was for an absolute beginner, I omitted TypeScript.

The API we create will be a simple hello world example, however the larger point is to showcase how I typically structure these types of projects to allow for an organized way of scaling it up to something larger. I'm always learning, so please let me know if you have any thoughts throughout this!

### Project Structure 🧬

```
.
├── package.json
├── pnpm-lock.yaml
└── src
    ├── application.js
    ├── controllers
    │   ├── ApiController.js
    │   └── HelloController.js
    ├── endpoints
    │   └── hello
    │       └── helloWorld.js
    └── index.js

4 directories, 7 files
```

### Setup 🔨

#### Initialize the project

Go ahead and create a new project folder and initialize it with a `package.json` using your package manager of choice. I've been experimenting with pnpm lately so the commands shown will be using that:

```bash
mkdir express-template && cd express-template
pnpm init -y
```

There are very few dependencies we need, so let's go ahead and install the following:

```bash
pnpm add express cors
pnpm add --save-dev nodemon
```

Now, let's add two scripts to run our application:

```bash
"scripts": {
  "dev": "nodemon ./src/index.js",
  "start": "node ./src/index.js"
},
```

Nodemon allows us restart the server automatically whenever 
we make changes to our codebase.

Before we write some code, let's add some of the folder structure to the project:

```bash
mkdir src
mkdir src/controllers
mkdir src/endpoints
mkdir src/endpoints/hello
```

#### Create the application class

I typically like to wrap my express application in a class that manages the server and database connection. While we won't be connecting a database in this template, we will create an empty function that would contain the connection logic.

create `src/application.js` and `src/index.js` and add the following:

```js
// application.js
const express = require("express");
const cors = require("cors");

class Application {
  expressApp;

  async connect() {
    // your database connection code would go here
  }

  init() {
    this.expressApp = express();

    this.expressApp.use(express.json());
    this.expressApp.use(express.urlencoded({ extended: true }));

    const corsOptions = {
      // this allows from all origins, you probably want to restrict this
      origin: "*", // FIXME: change me to fit your configuration
    };

    this.expressApp.use(cors(corsOptions));

    this.expressApp.get("/hello", (_, res) => res.send("Hello World!"));
  }

  start() {
    const PORT = process.env.PORT || 5000;

    this.expressApp.listen(PORT, () => {
      console.log(`Server listening at http://localhost:${PORT}`);
    });
  }
}

module.exports = Application;
```

```js
// index.js
const Application = require('./application');

async function main() {
  const application = new Application();
  await application.connect();
  application.init();
  application.start();
}

main();
```

To see that everything is working as expected, go to `http://localhost:5000/hello` in your browser and you should see 'Hello World' display on your screen.

#### Create an endpoint function

I like to organize my endpoints in the endpoints folder, nested in a subfolder that matches the controller it belongs to. For this simple application, we will just have a `hello` folder for the `HelloController` we will create in the next step.

Let's create a function to send a simple text response:

`src/endpoints/hello/helloWorld.js`
```js
const helloWorld = async (_req, res) => {
  res.send("Hello World!");
};

module.exports = helloWorld;
```

Now that we have a simple endpoint function, let's create our controllers to hook this up to our app.

#### Create the controllers

I usually have one parent controller I call the `ApiController`, which is then broken up into more controllers. To demonstrate this, create the following files:

`src/controllers/ApiController.js`
```js
const { Router } = require("express");
const HelloController = require("./HelloController");

const ApiController = new Router();

ApiController.use("/hello", HelloController);

module.exports = ApiController;
```

This will pass all requests with the `/hello` prefix to the HelloController.

`src/controllers/HelloController.js`
```js
const { Router } = require("express");
const helloWorld = require("../endpoints/hello/helloWorld");

const HelloController = new Router();

HelloController.get("/", helloWorld);

module.exports = HelloController;
```

When a GET request to `/hello` is made, our `helloWorld` function will now get run.

### Wrapping it all up

To finalize everything, we need to actually use our ApiController in the Application class. We can now replace the inline GET request definition with our controller:

```js
//     this.expressApp.get("/hello", (_, res) => res.send("Hello World!"));

this.expressApp.use("/api", ApiController);
```

And with that, we're done! You now have a very small, minimal template for getting started with REST APIs using Express. If you go to `http://localhost:5000/api/hello` in your browser, you should see the 'Hello World!' message.

Let me know if this was helpful or if you have any notes (I love notes - it's how we all get better!)