I am using json-server to simulate some api calls responses for front-end development turns out that adding a middleware does not really work out in my case:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "concurrently -k \"json-server --watch api-faked/db.json --routes api-faked/routes.json --middlewares api-faked/middleware.js --ro\" \"vue-cli-service serve\"",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
When starting:
[1] INFO Starting development server...
[0]
[0] \{^_^}/ hi!
[0]
[0] Loading api-faked/db.json
[0] Loading api-faked/routes.json
[0] Loading api-faked/middleware.js
[0] Done
[0]
It seems that the middleware.js
is considered by json-server, however, a simple example such as the middleware.js
like below:
module.exports = (req, res, next) => {
res.header('X-Hello', 'World')
next()
}
Does not add any header to my response headers:
Request URL: http://localhost:3000/api/v1/operations/?code_like=adi
Request Method: OPTIONS
Status Code: 204 No Content
Remote Address: 127.0.0.1:3000
Referrer Policy: no-referrer-when-downgrade
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: http://localhost:8080
Connection: keep-alive
Content-Length: 0
Date: Thu, 18 Jul 2019 12:23:53 GMT
Vary: Origin, Access-Control-Request-Headers
X-Powered-By: Express
What am I missing here?
Side-note: actually removing the next
from the middleware.js
does not even alter anything, it's like even though the middlware has been added to the json-server configuration it seems not really run at any point in time.
The solution in my case was using the module style of json-server, which basically involves creating a js
file and recreating router which is otherwise created automatically with the db.json
and routes.json
, unlike the automatic mode, it supports adding a middleware which can intercept pretty much everything.
Example
const fs = require('fs');
const jsonServer = require('json-server');
const path = require('path');
const server = jsonServer.create();
const defaultMiddleware = jsonServer.defaults();
// It is recommended to use the bodyParser middleware before any other middleware in your application
server.use(jsonServer.bodyParser);
server.use(defaultMiddleware);
// Define custom routes (routes.json)
const routes = JSON.parse(fs.readFileSync(path.join(__dirname, 'routes.json')));
server.use(jsonServer.rewriter(routes));
// Add custom middleware before JSON Server router
const customMiddleware = require(path.join(__dirname, 'middleware.js'));
server.use(customMiddleware);
// This is where `json-server`'s magic happens ;)
const router = jsonServer.router(path.join(__dirname, 'db.json'));
// Start the application by listening to port 3000,
// Although this won't print the nice starting message you see when
// running `json-server` as CLI command, it still runs the app correctly.
server.use(router);
server.listen(3000, () => {
console.log('JSON Server is running')
});
With the structure of the folder api-faked
being:
server.js
middleware.js
db.json
routes.json
Instead of serving the application like that (in package.json
):
"serve": "concurrently -k \"json-server --watch api-faked/db.json --routes api-faked/routes.json --middlewares api-faked/middleware.js --ro\" \"vue-cli-service serve\"",
it is now like this:
"serve": "concurrently -k \"nodemon api-faked/server.js --watch api-faked/*.*\"
I also use nodemon which restart the json-server if any change occurs in any of the given files (ie. --watch api-faked/*.*
)
I've been put on the right track thanks to the answer given in that GitHub issue: json-server does not use the code provided in the middleware file