Following from Part 1 and Part 2, we had a working server but the changes are lost when server is restarted π . That sucked, so now time to database the, err ... data! πΎππ₯«
(π₯« <- this is supposed to be a database)
NoSql databases
Compared to SQL databases with tables and rows, NoSql has collections and documents:
database > collections > documents
For example:
(database) data_db >
(collection) movies: [{}, {}, {}] >
(document) movie: { "id": "tt0110357", "name": "The Lion King", "genre": "animation"},
For details on the whole SQL vs NoSql, check out this article:
What is diskdb
?
Diskdb allows you to use a file-based database with a mongodb-like API. Think SQLite for mongo. But why?
- Quick, simple, and fast - no more installation or config files; perfect for whipping a prototype server with some persistence
- db is stored along with your code, in regular JSON file, so easy to maintain without extra tooling
- No sign-up needed - No more signing up and getting tons of emails
why not?
- Very simple with limited API functionality
- Really not for Production
For the record, I loved mLab since it was easy, fast and free up to 500MB. But it was recently acquired by MongoDB and replaced with Atlas. I'll make a separate article for a cloud-based DB with Atlas as well.
Headstart
We'll use the base server files from the previous lesson here:
Quick REST API with Node + Express
Let's get started!
1. Create database file
Create /data/movies.json
.
Data will be our database and movies will be our collection.
...
data/
/movies.json
server.js
...
Init movies.json
with an empty array
[]
2. Exclude data files from Nodemon
If you are using nodemon, you wouldn't want the server to restart for every change in the database files, i.e. an infinitely restarting server π΅
Add nodemonConfig
to package.json
, with a command to ignore /data
.
"scripts": {...},
"nodemonConfig": { "ignore": [ "data/*" ] },
...
3. Install diskdb
$ npm install diskdb
4. Import and connect to db
The syntax is:
db.connect('/path/to/db-folder', ['collection-name']);
// server.js
...
// diskdb connection
const db = require('diskdb');
db.connect('./data', ['movies']);
This effectively creates a connection to the 'data' db, and 'movies' collection.
4. Add a movie to test out connection
// server.js
...
// add first movie
if (!db.movies.find().length) {
const movie = { id: "tt0110357", name: "The Lion King", genre: "animation" };
db.movies.save(movie);
}
console.log(db.movies.find());
Nice and simple!
db.[collection].save(object)
to add a document
db.[collection].find()
to get all current docs
We're only adding this movie if the db is initially empty,
or else we'll end up with lots of Lion King
s with different _id
s π¨
π¦π¦π¦π¦π¦π¦π¦
This should give you something like this
Successfully connected to : ./data
[ { id: 'tt0110357',
name: 'The Lion King',
genre: 'animation',
_id: 'fed8db042fac4892bb96fd72ad13290e' } ]
Notice that it added a _id
to our item, used as a global id like in mongodb.
5. CRUD to REST to DB
Now that you've seen Create and Read all, here's the complete roundup of the db operations in diskdb syntax for each CRUD - REST route handler.
For details on the REST - HTTP table and route handlers, check out prev post .
Also note that collection
here is movies for our example.
CRUD Operation | REST operation | Diskdb Operation |
---|---|---|
Create | POST /items
|
db.[collection].save(object) |
Read One | GET /items/:id
|
db.[collection].find(query) |
Read All | GET /items
|
db.[collection].find() |
Update | PUT /items/:id
|
db.[collection].update(query, data, options) |
Delete | DELETE /items/:id
|
db.[collection].remove(query, multi) |
6. Changing to diskdb operations
Using the table, we could now replace all of our memory-based operations with the db equivalent.
i. Create β
server.post("/items", (req, res) => {
const item = req.body;
console.log('Adding new item: ', item);
// add new item to db
db.movies.save(item);
// return updated list
res.json(db.movies.find());
});
ii. Read one π΅οΈ
server.get("/items/:id", (req, res) => {
const itemId = req.params.id;
const items = db.movies.find({ id: itemId });
if (items.length) {
res.json(items);
} else {
res.json({ message: `item ${itemId} doesn't exist` })
}
});
iii. Read all π΅οΈ
server.get("/items", (req, res) => {
res.json(db.movies.find());
});
iv. Update βοΈ
server.put("/items/:id", (req, res) => {
const itemId = req.params.id;
const item = req.body;
console.log("Editing item: ", itemId, " to be ", item);
db.movies.update({ id: itemId }, item);
res.json(db.movies.find());
});
v. Delete β
server.delete("/items/:id", (req, res) => {
const itemId = req.params.id;
console.log("Delete item with id: ", itemId);
db.movies.remove({ id: itemId });
res.json(db.movies.find());
});
Test it out
Add a new one.
$ curl -X POST -H "Content-Type: application/json" --data '{"id": "tt0109830", "name": "Forrest Gump", "genre": "drama"}' http://localhost:4000/items
Fetch all.
From browser: http://localhost:4000/items
Fetch one.
From browser: http://localhost:4000/items/tt0110357
Update it.
Maybe you think Forrest Gump is an action movie, because of all the war sequences and all the running. π«ποΈπββοΈ
$ curl -X PUT -H "Content-Type: application/json" --data '{"genre": "action"}' http://localhost:4000/items/tt0109830
...{"id":"tt0109830","name":"Forrest Gump","genre":"action"}...
Delete it.
curl -X DELETE http://localhost:4000/items/tt0468569
Some cleanup π§Ή
Db is working! Now we can remove the unneeded static data file: data.js
.
Don't forget to remove the line from server.js
that imports it
let data = require('./data');
Here's the complete Code
Quick db with Node + Express + diskdb
"Okay, that was nice. But what can I do with this? "
β
Serving HTML files
β
REST API
β
Database persistence
Now, this is an actual server for a small project. Add more routes, save some data in the db through API requests. And when you want to reset the db, just reset movies.json
to [].
Next up:
(In progress): Using a Cloud DB with Node and Express
This article is part of a Node+Express series I'm working on.
For the meantime, if you can't get enough of Node+Express π€,
checkout my Node workshop (Gihub repo and slides):
lenmorld / node_workshop
Build a server and API for your next web application, using Node, Express and MongoDB
Node workshop
Create a server + REST API for your next web application!
In this workshop, weβll discuss concepts and put them to practice with activities, all about web servers The code and concepts here would be a great foundation for your next web project Topics include, but not limited to:
- Using Node and Express to build a web server and REST API
- Understanding routing, request and response
- Implementing CRUD with HTTP methods
- Building a server-rendered website using templates
- Connecting to a Cloud NoSQL database: MongoDB Atlas DB
- User authentication with sessions, cookies and tokens
- Using external APIs, such as Github Jobs, Giphy, Spotify
Previous Events
Material
Preview slides: Google Drive document
Material: Notion link
Code
to follow workshop:
$ git checkout dev
$ node server.js
to dev latest
$ git checkout master
$
β¦
Here we discussed:
- Using Node and Express
- Routing, request and response
- Building a REST API
- Server-rendered templates
- Connecting to a NoSQL (mongo) database
- Using external APIs, such as Spotify
- and much more!
Happy server-ing! π€
Now, if I could find a better emoji for a database than π₯«
Top comments (6)
Thanks, this was very handy as a dev db for demos or when backend are slacking, hehe.
I use this and added collection as a parameter.
Awesome articles, this was fantastic in helping me setup and get an understanding of API with Express and nodejs.
Can't wait for the 'Using a Cloud DB with Node and Express' part to come out!
Really enjoying these straight-to-the-point tuts. Just wanted to mention your "Test it out" section has the "Fetch one" and "Fetch all" URL's the wrong way around!
Thanks for the catch.π I updated that part.
I'm gonna get to the next article of this series soon. I really appreciate the support π
Thanks...You made it really simple :-)
I'm back!
Cloud DB with Node and Express finally here ππβ
π± Complete REST API with MongoDB Atlas cloud, Node, and Express in 10 minutes
Lenmor Ld γ» Dec 7 γ» 9 min read