Node.js
fs persistence
Save and load data as JSON with fs.
File persistence
Routes live in memory; they are lost when the server restarts. To make data persistent we write it to a file with the fs module. fs.writeFileSync(path, data) writes data synchronously; fs.readFileSync(path, 'utf8') reads the file as a string.
To store the user list you write a saveUsers(data) function: fs.writeFileSync(DB_PATH, JSON.stringify(data)). Here JSON.stringify turns the object into a string. You restore it with loadUsers(): JSON.parse(fs.readFileSync(DB_PATH, 'utf8')). JSON.parse turns the string back into an object. This way data persists in a file; it stays on disk even if the server crashes.
Save and load
In this lesson we add the saveUsers and loadUsers functions. saveUsers({users: ['Ayşe', 'Alex']}) writes the data to a file; loadUsers() reads the file and returns the object. Calling them in sequence makes the data persistent.
First we import the module with const fs = require('fs'). We pin the file path with const DB_PATH = '/tmp/nodejs-i20.json' and reuse it. saveUsers handles writing, loadUsers handles reading. Finally console.log('Loaded: ' + JSON.stringify(loadUsers())) verifies the data was restored. The output is the string form of the saved object.
Exercise Add fs persistence
Import with const fs = require('fs'). Define const DB_PATH = '/tmp/nodejs-i20.json'. Write function saveUsers(data) { fs.writeFileSync(DB_PATH, JSON.stringify(data)); }. Write function loadUsers() { return JSON.parse(fs.readFileSync(DB_PATH, 'utf8')); }. Call saveUsers({users: ['Ayşe', 'Alex']}). Print console.log('Loaded: ' + JSON.stringify(loadUsers())).
Show example solution
const express = require('express');
const app = express();
const routes = [];
app.get('/health', (req, res) => res.json({ok: true}));
routes.push({method: 'GET', path: '/health'});
console.log('Server ready');
app.get('/users', (req, res) => res.json([]));
routes.push({method: 'GET', path: '/users'});
app.post('/users', (req, res) => res.json({created: true}));
routes.push({method: 'POST', path: '/users'});
console.log('Routes: ' + routes.map(r => r.method + ' ' + r.path).join(', '));
const fs = require('fs');
const DB_PATH = '/tmp/nodejs-i20.json';
function saveUsers(data) {
fs.writeFileSync(DB_PATH, JSON.stringify(data));
}
function loadUsers() {
return JSON.parse(fs.readFileSync(DB_PATH, 'utf8'));
}
saveUsers({users: ['Ayşe', 'Alex']});
console.log('Loaded: ' + JSON.stringify(loadUsers()));
Test yourself
-
Match each piece to its role
- writeFileSync
- Writes data to a file
- readFileSync
- Reads the file as a string
- JSON.stringify
- Turns an object into a string
- JSON.parse
- Turns a string into an object
-
What does JSON.stringify({users: ['Ayşe']}) produce?
JSON.stringify({users: ['Ayşe']})
- {users: ['Ayşe']}
- users:Ayşe
- [Ayşe]
- {"users":["Ayşe"]}
Show answer
{"users":["Ayşe"]} — JSON.stringify turns the object into the string {"users":["Ayşe"]}.
-
Complete the writeFileSync line
fs.writeFileSync(DB_PATH, JSON.____(data));
Show answer
fs.writeFileSync(DB_PATH, JSON.stringify(data));
Next lesson: Middleware