Next.js - Read/Write Data to JSON Files as the Database
Tutorial built with Next.js 11.1.0
This is a quick post to show how to manage (read/write) data in a JSON flat file with Next.js, it's useful for building example apps or for when you need to get up and running quickly before setting up a full database such as MongoDB, MySQL, SQL Server etc.
The below code snippets are taken from a Next.js login tutorial I posted recently, for the full tutorial or to download and test the code locally see Next.js 11 - User Registration and Login Tutorial with Example App.
To keep the Next.js tutorial as simple as possible, instead of a database it stores user data in a JSON flat file located at /data/users.json
, the data is accessed and managed via the users repo which supports all basic CRUD operations.
Users JSON Data File
A JSON file containing user data for the Next.js tutorial app, the data is accessed and managed via the users repo which supports all basic CRUD operations. The file contains an empty array ([]
) by default which is first populated when a new user is registered.
[]
Users Repo to Read/Write JSON File
The users repo encapsulates all read/write access to the users JSON data file and exposes a standard set of CRUD methods for reading and managing the data. It's used on the server-side by the Next.js users API route handlers (e.g. the register route handler).
const fs = require('fs');
// users in JSON file for simplicity, store in a db for production applications
let users = require('data/users.json');
export const usersRepo = {
getAll: () => users,
getById: id => users.find(x => x.id.toString() === id.toString()),
find: x => users.find(x),
create,
update,
delete: _delete
};
function create(user) {
// generate new user id
user.id = users.length ? Math.max(...users.map(x => x.id)) + 1 : 1;
// set date created and updated
user.dateCreated = new Date().toISOString();
user.dateUpdated = new Date().toISOString();
// add and save user
users.push(user);
saveData();
}
function update(id, params) {
const user = users.find(x => x.id.toString() === id.toString());
// set date updated
user.dateUpdated = new Date().toISOString();
// update and save
Object.assign(user, params);
saveData();
}
// prefixed with underscore '_' because 'delete' is a reserved word in javascript
function _delete(id) {
// filter out deleted user and save
users = users.filter(x => x.id.toString() !== id.toString());
saveData();
}
// private helper functions
function saveData() {
fs.writeFileSync('data/users.json', JSON.stringify(users, null, 4));
}
Register API Route Handler
The register handler receives HTTP requests sent to the register route /api/users/register
. It supports HTTP POST
requests containing user details which are registered in the Next.js app by the register()
function.
The register()
function uses the usersRepo.find()
method to validate that the username is unique, and the usersRepo.create()
method to save the user details to the JSON data file. On successful registration a 200 OK
response is returned with an empty JSON object.
The route handler supports HTTP POST
requests by passing an object with a post()
method to the apiHandler()
wrapper function. For more info on the API handler wrapper function see the full tutorial linked at the top of the post.
const bcrypt = require('bcryptjs');
import { apiHandler, usersRepo } from 'helpers/api';
export default apiHandler({
post: register
});
function register(req, res) {
// split out password from user details
const { password, ...user } = req.body;
// validate
if (usersRepo.find(x => x.username === user.username))
throw `User with the username "${user.username}" already exists`;
// hash password
user.hash = bcrypt.hashSync(password, 10);
usersRepo.create(user);
return res.status(200).json({});
}
Need Some NextJS Help?
Search fiverr for freelance NextJS developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!