👋 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:
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:
pnpm add express cors
pnpm add --save-dev nodemon
Now, let's add two scripts to run our application:
"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:
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:
// 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;
// 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
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
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
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:
// 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!)
Top comments (0)