Hi, is it possible to watch a "db.json" file using json-server as module? I have used:
var jsonServer = require('json-server');
var server = jsonServer.create();
var router = jsonServer.router('db.json');
var middlewares = jsonServer.defaults({ watch : true });
server.use(middlewares);
server.use(router);
server.listen(3001, function () {
console.log('JSON Server is running')
});
Also I noticed it does not save my changes with POST request on "db.json" file. Is it correct? Does it only work on CLI? It only persist the data in memory, but when I check the file it still contains the same data when I ran the server.
Thanks.
Hi @sant123,
watch is not included in the module, it's only available in the CLI.
I preferred to not include it in the module as usually tools used to watch .js file can watch .json files too. And also, I don't feel it should be part of the middlewares.
I would suggest using nodemon:
$ nodemon server -e db.json
Hi @typicode, I was thinking exactly in Nodemon but this restarts my whole server and it takes a while to do it, that's not the case of CLI watch because it only restarts lowdb and everything keeps working. I think this functionality would be good inside Json-server module for what I said, and I'll appreciate it if this is part of it.
Thank you!
@typicode is there a way to include something like this? gulp-json-server#reloaddata.
Because in this part, each user would implement their own watcher system, with the difference they will have a method that will restart the module and load again db.json file. The code I use in gulp is this:
(function() {
var gulp = require("gulp");
var jsonServer = require("gulp-json-srv");
var server = require("gulp-server-livereload");
var folder = "web";
var dbName = "db.json";
var webServerPort = 8693;
var jsonServerPort = 8694;
var serverInstance = jsonServer.start({
data: dbName,
port: jsonServerPort,
deferredStart: true
});
gulp.task("web-server", function() {
gulp.src(folder).pipe(server({
livereload: true,
directoryListing: {
enable: true,
path: folder
},
open: true,
port: webServerPort
}));
});
gulp.task("json-server", function() {
serverInstance.start();
});
gulp.task('watch', function() {
gulp.watch([dbName], function() {
serverInstance.reload();
});
});
gulp.task("default", ["web-server", "json-server", "watch"]);
})();
With serverInstance.reload(); I can reset the json-server and then load it again.
Thanks.
+1 for this, it would be handy to include watch when using the module if possible
I'm not sure you even need to include watch.. maybe just a 'no cache' option so that the file is re-read each time. For me the API speed is not an issue, so the performance gain of pre-loading the file is irrelevant.
For your own risk here is what you can do (maybe place it in middleware):
router.db.assign(require('require-uncached')('./db.json')).write();
I too need this feature as my middleware is actually potentially changing the data and need the updated data to be returned.
@szarouski I tried adding that package and line to my server.js, however it does not seem to do anything. I added it both the middleware I am using, as well as prior to the server.use(router); line. Did you have success with it and provide more info?
@bduff9 here is how I use it:
server.get('/tests-refresh', (req, res) => {
router.db.assign(requireNew('./db.json')).write();
res.sendStatus(200);
});
This code goes before server.use(router);. Not sure why it doesn't work for you.
@szarouski Thank you very much for the info, that helped. I had it in the right place the first time, I just had forgotten to await my db update, hence why I didn't see the updated data. Thanks again!
@szarouski thanks for this, I was looking how to update the db when using in memory, and your suggestion worked.
where is this syntax .assign().write() from?
Also really wanted this feature, I'm building a desktop CLI type app with a local front end that needs to subscribe to updates from lowdb, I start the server using a module as it's configured with application layer environment variables which aren't accessible via the command line (they're stored in the .env file).
So, I made a custom middleware to do this, I'm using fs-extra and have used @szarouski's example too. Here's how I've set it up:
const middlewares = [
...jsonServer.defaults({ readOnly: true }),
...[
(req, res, next) => fs
.readJson(file)
.then(contents => {
router.db.assign(contents).write();
next();
})
]
];
Works a treat.
Really need this feature. @szarouski Thank u very much, it worked!
server.use((req, res, next) => {
server.db.assign(require('require-uncached')('..\\db.json')).write();
// Continue to JSON Server router
next()
});
nodemon server -e db.json
Just a tip, I found the -e caused it to not watch for me, and isn't needed as nodemon auto watches .json files
I used.
"scripts": {
"start": "nodemon ./server.js"
},
Most helpful comment
+1 for this, it would be handy to include watch when using the module if possible