1: Create A New Directory for your application
Create a new directory for our Express server.
mkdir express-api
Change your directory so that you are inside the newly created folder
cd express-api
Initialize your package.json
file.
pnpm init
2: Add The Project Dependencies
Install the Express Framework
pnpm i express
Install Typescript
pnpm i -D typescript @types/express @types/node
Initialize your tsconfig.json
file.
pnpm tsc --init
Inside of the newly created tsconfig.json
file, declare your outDir
.
- // "outDir": "./", /* Specify an output folder
+ "outDir": "./dist", /* Specify an output folder
3: Write your Express Server:
Create a new src
folder.
mkdir src
Create your app.ts
file. This is where your server code will live.
touch src/app.ts
Add your server code:
import express from 'express';
const PORT = 5000;
const app = express();
app.get('/api', (req, res) => {
res.send('Server Running...');
});
app.listen(PORT, () => {
console.log(`Server listening at http://localhost:${PORT}/api...`);
});
export default app;
4: Run Your New Express Server
Compile your typscript
code. The compiled code will be saved in the ./dist
directory from step 2 above.
pnpm tsc
Run the compiled server code
node ./dist/app.js
5: Add an Endpoint with Return Data
Let's create a new route so that we can serve up some data. Since our data object is made up of different members of The Beatles, we will call our route /api/beatles
app.get('/api/beatles', (req, res) => {
const data = {
title: 'The Beatles',
beatles: [
{
'first name': 'John',
'last name': 'Lennon',
instrument: 'Guitar',
},
{
'first name': 'Paul',
'last name': 'McCartney',
instrument: 'Bass Guitar',
},
],
};
res.json(data);
});
The fully updated file will look like this:
import express from 'express';
const PORT = 5000;
const app = express();
app.get('/api', (req, res) => {
res.send('Server Running...');
});
app.get('/api/beatles', (req, res) => {
const data = {
title: 'The Beatles',
beatles: [
{
'first name': 'John',
'last name': 'Lennon',
instrument: 'Guitar',
},
{
'first name': 'Paul',
'last name': 'McCartney',
instrument: 'Bass Guitar',
}
],
};
res.json(data);
});
app.listen(PORT, () => {
console.log(`Server listening at http://localhost:${PORT}/api...`);
});
export default app;
Let's repeat step 4 above by running:
pnpm tsc
node ./dist/app.js
Now, if you go to http://localhost:5000/api/beatles, you will see that our Beatles data is being served for us!
Next, let's see what happens if we add one more Beatle to our data object. Without stopping the server let's go ahead and make the following update:
import express from 'express';
const PORT = 5000;
const app = express();
app.get('/api', (req, res) => {
res.send('Server Running...');
});
app.get('/api/beatles', (req, res) => {
const data = {
title: 'The Beatles',
beatles: [
{
'first name': 'John',
'last name': 'Lennon',
instrument: 'Guitar',
},
{
'first name': 'Paul',
'last name': 'McCartney',
instrument: 'Bass Guitar',
}
],
};
res.json(data);
});
app.listen(PORT, () => {
console.log(`Server listening at http://localhost:${PORT}/api...`);
});
export default app;
But wait... If you look back to http://localhost:5000/api/beatles, our beatles data didn't change, we don't have our third Beatle!
6: Add Hot Reloading:
We can fix this by adding some additional npm packages to help us watch our code for changes.
Go ahead and stop your server by hitting ctrl-c
or ctrl-d
on your keyboard.
Add nodemon
and ts-node
pnpm i -D nodemon ts-node
Next, open up your package.json and add the following start
script. We are going to just delete the test
script, but you can leave it if you prefer:
"scripts": {
"start": "nodemon --watch 'src/**' --ext 'ts,json' --exec 'ts-node src/app.ts'"
},
Let's go ahead and run our server once more.
pnpm start
You will see the following in your terminal:
➜ express-api pnpm start
> express-api@1.0.0 start /your/directory/path/your-project-name
> nodemon --watch 'src/**' --ext 'ts,json' --exec 'ts-node src/app.ts'
[nodemon] 3.0.1
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): src/**
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src/app.ts`
Server listening at http://localhost:5000/api...
Now, if you go back to http://localhost:5000/api/beatles, you will see all three of our Beatles.
To make sure that our server code is actually hot-reloading, let's add one more Beatle to our data object.
Go ahead and add
{
'first name': 'Stag',
'last name': 'Beetle',
instrument: 'Mandible Harp',
}
Your updated server code should now look like this:
import express from 'express';
const PORT = 5000;
const app = express();
app.get('/api', (req, res) => {
res.send('Server Running...');
});
app.get('/api/beatles', (req, res) => {
const data = {
title: 'The Beatles',
beatles: [
{
'first name': 'John',
'last name': 'Lennon',
instrument: 'Guitar',
},
{
'first name': 'Paul',
'last name': 'McCartney',
instrument: 'Bass Guitar',
},
{
'first name': 'George',
'last name': 'Harrison',
instrument: 'Lead Guitar',
},
{
'first name': 'Ringo',
'last name': 'Starr',
instrument: 'Drums',
},
{
'first name': 'Stag',
'last name': 'Beetle',
instrument: 'Mandible Harp',
},
],
};
res.json(data);
});
app.listen(PORT, () => {
console.log(`Server listening at http://localhost:${PORT}/api.`);
});
export default app;
If you go back to http://localhost:5000/api/beatles one last time, then you will see that unlike the last time we added a Beatle, our new beatle has been added to our API route without having to stop our server!
Conclusion
Note, in a typical express server, you wouldn't have your data sitting directly in your route like we did here.
The full code repository can be found at github.com/benjamin-chavez/node-pg-knex-passport-template.
If you found this post useful, then stay tuned for more posts as I document my journey building a multi-vendor marketplace for music producers.