Json-server: Include watch db in json-server as module.

Created on 13 May 2016  路  14Comments  路  Source: typicode/json-server

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.

Most helpful comment

+1 for this, it would be handy to include watch when using the module if possible

All 14 comments

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?

@dseeker, you're welcome; router.db is an instance of lowdb.

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"
  },
Was this page helpful?
0 / 5 - 0 ratings

Related issues

goldmont picture goldmont  路  3Comments

bahmutov picture bahmutov  路  3Comments

melnikovic picture melnikovic  路  3Comments

dotmobo picture dotmobo  路  4Comments

pantchox picture pantchox  路  3Comments