Spin up a Node.js/Express server and a Postgres database
Quick steps to create a Node.js, Express, and Postgres playground.
Sometimes I'm experimenting with a quick idea and I want to spin up a server and database for it on localhost. There are a handful of quick steps I take out of the gate to get up and running with Node.js, Express, and Postgres.
For the remainder of this post, I'll show what those steps are. I'll skip in-depth explanations, and focus on the setup.
If you follow the steps, by the end, you'll be able to make an API call via cURL or Postman to a server on localhost, which will in turn read from or write to the database and return the result to your client.
I will note here at the outset that the end result is a playground for experimentation, and in no way is it production-ready.
I hope this is helpful. Happy hacking!
Create a folder
Any folder name will do:
mkdir server && cd server && git init
Any CLI commands you see below all happen in this folder, the root of the project.
Express generator
Generate your Express server (with a default .gitignore
file and without a view engine):
npx express-generator --git --no-view
Done. We used npx
because we won't need express-generator
again. Since I only need this module once per project, I prefer not to install it globally.
Nodemon
Add nodemon
to your project to auto-restart your server when you edit files:
npm i -S nodemon
Then, in package.json
, modify the default start
script to use nodemon
instead of node
:
"scripts": {
"start": "nodemon ./bin/www"
},
This step isn't crucial to getting set up, but is a solid lifestyle upgrade, so I prefer to go ahead and do it early.
Sequelize
This section contains the most steps, but shouldn't take much time to do.
Initialize sequelize
Add sequelize
, pg
, and sequelize-cli
to your project, then initialize your sequelize project.
npm i -S sequelize pg
npm i -D sequelize-cli
npx sequelize init
I install sequlize-cli
as a dev dependency locally (as opposed to running npx
without the install) because I use this CLI a number of times over the course of a project, and I want the CLI to be there even if I'm not connected to the internet.
Configure your database
The sequelize CLI created a config/config.json
file. Switch out the content of the file with the following (you can change the name in the database
fields to whatever you prefer):
{
"development": {
"username": "",
"password": "",
"database": "node_server_database_development",
"dialect": "postgres",
"protocol": "postgres"
},
"test": {
"username": "",
"password": "",
"database": "node_server_database_test",
"dialect": "postgres",
"protocol": "postgres"
},
"production": {
"username": "",
"password": "",
"database": "node_server_database_production",
"dialect": "postgres",
"protocol": "postgres",
"use_env_variable": "DATABASE_URL"
}
}
Timely reminder: this is not prod-ready, but fine for noodling around on localhost.
Create your database
A short one-liner:
npx sequelize db:create
If you run into issues here, check the config/config.json
file in the previous step.
Generate a model
Make, as a random example, a User model:
npx sequelize model:generate --name User --attributes username:string,email:string,password:string
For some reason, model generation via CLI is documented only in the sequelize CLI's FAQ. Since you'll most likely create more models, you may want to keep that link handy.
Connect and sync the database on server start
Open /bin/www
and add the sequelize instance that was generated by the CLI as a dependency:
const sequelize = require("../models").sequelize;
Then in the same file, find the server.listen(port)
line, and replace it with this:
sequelize
.sync({ alter: true }) // Not recommended for production use.
.then(() => {
server.listen(port);
})
.catch((err) => {
console.log(err);
});
You can learn more about the .sync()
method in the sequelize docs. I use the alter
option locally because I may end up revising my models frequently, and this will keep my db tables up-to-date with my latest models.
Express routes
Almost there! Lastly, throw a couple of basic routes into routes/users.js
:
const express = require("express");
const router = express.Router();
const { User } = require("../models");
router.get("/", async (req, res, next) => {
try {
const users = await User.findAll();
res.json(users);
} catch (error) {
next(error);
}
});
router.post("/", async (req, res, next) => {
try {
const user = await User.create(req.body);
res.json(user);
} catch (error) {
next(error);
}
});
module.exports = router;
You've got a route for getting all users, and a route for creating a single user.
Since these routes are in the routes/users.js
file, the endpoints will be accessible at localhost:3000/users
(via GET and POST methods, respectively).
We're done with the setup!
Try it
Start up your server:
npm start
Now you can try hitting the API with cURL with a request to create a user:
curl --location --request POST 'localhost:3000/users/' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=ash' \
--data-urlencode 'email=ash@node.server' \
--data-urlencode 'password=nodeserverftw'
You should get back a response that looks like this:
{"id":1,"username":"ash","email":"ash@node.server","password":"nodeserverftw","updatedAt":"2020-07-30T00:25:42.226Z","createdAt":"2020-07-30T00:25:42.226Z"}
Or you can get all users:
curl --location --request GET 'localhost:4000/users/' --header 'Content-Type: application/x-www-form-urlencoded'
Which returns an array containing the single user we just created:
[{"id":1,"username":"ash","email":"ash@node.server","password":"nodeserverftw","createdAt":"2020-07-30T01:28:03.032Z","updatedAt":"2020-07-30T01:28:03.032Z"}]
Your Node.js, Express, and Postgres playground is ready. Have fun!
There are lot of ways to go about spinning up a local project, surely much better ones if you are on the path to building a production server!
If you're looking for something simple and quick, I hope this setup is helpful.