- Published on
Setting Up a Simple Express Server
- Authors
- Name
- Nali Thephavong Haehn
This tutorial will walk you through creating a standalone Express application that serves dummy order data. We'll incorporate basic concepts of RESTful web services and an MVC-like design pattern to create an app that you can use as a template for simple or complex APIs. No frontend, no database, just the basics.
Link to repository: GitHub
NOTE |
---|
This post was meant as a reference for quickly deploying an Express app, so I'm leaving out much of the why and focusing on the how. Be sure to bookmark this for future reference. |
Pre-requisites
- Install Node.js. I am using version 18.17.1, as of writing, but anything >= 16 should be sufficient.
HOT TIP |
---|
To check which version of node is installed, use the command node --version in a terminal window. |
Setup Project Folder Structure
For very simple projects, you can get away with writing code in the entry point file (typically, something like app.ts
or index.ts
) located directly under the main folder, but if you are doing anything more complex you should be segregating your logic into easily readable components. In this case, we'll use something akin to MVC.
- Create a folder for your project files, I created
express_example
. - Create the following folders under your main folder:
routes
,controllers
,models
.
NOTE |
---|
You can also have a views folder if you plan to create an integrated UI with ejs templates, but I prefer to use Express as a backend for a standalone React frontend, so we won't need that here. Also, yes, mono-repos are gaining popularity, but that's not what we're doing here. |
At the end of this tutorial, you should have a folder structure that looks like this:
express_example
├── controllers
│ └── orders-controller.ts
├── models
│ └── orders-model.ts
├── package.json
├── routes
│ └── orders-route.ts
├── server.ts
└── tsconfig.json
Instantiate Node Project
In a terminal window, navigate to the
express_example
folder and run the command:npm init -y
.This will generate a package.json file in
express_example
. The-y
switch is to suppress the prompts, but if you'd prefer to go through the setup wizard, then you can remove it.Run the following command to install dependencies:
npm install express dotenv cors body-parser
Run the following to install dev-only dependencies:
npm install -D @types/cors @types/express @types/node nodemon typescript
NOTE |
---|
You can also use yarn to install packages, but for simplicity, I will use npm which is included in the Node.js package. |
Create a tsconfig.json File
This file is used to transpile your typescript files into javascript.
Under your express_example
folder, create a file named tsconfig.json
. Paste the following code in the file:
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"outDir": "./dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
Write Express Entry Point Script
Under the express_example
folder, create a file named server.ts
. This will be where you instantiate your Express app.
NOTE |
---|
I prefer to use server vs. app/index in this case as it's more indicative of what we're doing (setting up a backend server). If you do decide to use app or index, make sure all references to server are changed accordingly. |
Paste the following code in your file:
import express, { Express, Request, Response, NextFunction } from 'express';
import dotenv from 'dotenv';
import cors from 'cors';
import { json } from 'body-parser';
dotenv.config();
const app: Express = express();
const port = process.env.PORT || 8000;
app.use(cors());
app.use(json());
app.get('/', (req: Request, res: Response) => {
res.json({message:'Simple Express Server'});
});
app.use((err: Error, req: Request, res:Response, next: NextFunction) => {
res.status(500).json({message: err.message});
});
app.listen(port, () => {
console.log(`[server]: Server started at http://localhost:${port}`);
});
Create a Model File
Since we are returning information about orders, we'll create a model for an order with very basic fields.
Under the models
folder, create an orders-model.ts
file with the following information:
export class Order {
orderdate: string;
id: string;
customer: string;
total: string;
status: string;
shipdate: string;
trackingnumber:string;
constructor (
orderdate: string,
id: string,
customer: string,
total: string,
status: string,
shipdate: string,
trackingnumber:string
) {
this.orderdate = orderdate;
this.id = id;
this.customer = customer;
this.total = total;
this.status = status;
this.shipdate = shipdate;
this.trackingnumber = trackingnumber;
}
}
Create a Controller File
This is where all of the logic for our route lives.
Under the controllers
folder, create an orders-controller.ts
file, with the following code:
import { Request, Response, NextFunction } from 'express';
import { Order } from '../models/orders-model';
// DO NOT USE THIS IN PRODUCTION
// THIS IS JUST TO INITIALIZE TEST DATA
let ORDERS: Order[] = [
{
orderdate: '2023-08-01',
id: '20000001',
customer: 'A Popular Donut Place',
total: '457.89',
status: 'New',
shipdate: '',
trackingnumber: ''
},
{
orderdate: '2023-08-02',
id: '20000002',
customer: 'Another Popular Donut Place',
total: '975.42',
status: 'In Process',
shipdate: '',
trackingnumber: ''
}
];
// #region MAIN FUNCTIONS
export const getOrders = (req: Request, res: Response, next: NextFunction) => {
return res.status(200).json({
"orders": ORDERS
});
}
// #endregion
Create Your First Route
Associate the getOrders
function from the controllers file with our main GET route.
Under the routes
folder, create an orders-route.ts
file:
import { Router } from 'express';
import { getOrders } from '../controllers/orders-controller';
const router = Router();
router.get('/', getOrders);
router.post('/');
router.patch('/:id');
router.delete('/:id');
export default router;
Update Your Entry Point Script
Tie all of the code together in the entry point file.
Open server.ts
and add the lines of code designated by the arrow:
//...
import { json } from 'body-parser';
import ordersRoutes from './routes/orders-route'; //<---
//...
app.use(json());
app.use('/orders', ordersRoutes); // <---
app.get('/', (req: Request, res: Response) => {
res.json({message:'Simple Express Server'});
});
//...
Prepare to Run Your App
Open the package.json
file and update the scripts
section. Also, make sure the main
tag aligns with the name of your entry point file:
{
"name": "express_example",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "npx tsc",
"start": "node dist/server.js",
"dev": "npm run build && nodemon -q dist/server.js"
},
...
}
Run Your App
Open a terminal window and navigate to express_example
, then run npm run dev
. This will compile your files into javascript and serve them up on localhost port 3000 (unless a different port was specified in server.ts
).
Navigating to http://localhost:3000/orders will return the list of orders from your controller.