Use middleware only for json server specific routes - javascript

How can I use a middleware ONLY FOR my json-server specific routes? In the json-server docs, I can see the following instructions:
const jsonServerRouter = jsonServer.router('mock-server/db.json')
server.use(customMiddleware)
server.use(jsonServerRouter) // customMiddleware should be executed ONLY FOR this jsonServerRouter
/*
Problem is here, customMiddleware has already been executed,
so following routes will use the middleware too
*/
server.use(otherRoutes)
What I've tried:
// This syntax is similar to the previous code. So it doesnt work
server.use(customMiddleware, jsonServerRouter)
// Passing the middleware to the 'router' function doesnt work
const jsonServerRouter = jsonServer.router('mock-server/db.json', customMiddleware)

Related

Next.js middleware matcher negate path

I have a middleware on a Next.js project, and I want to negate my /api/* route.
In other words, I want middleware to run for every route except anything that starts with /api/. I couldn't find an example in the docs.
How do I achieve that (of course, without writing all included routes one by one)?
Looks like the middleware docs have been updated to account for something like this.
nextjs middleware docs
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - static (static files)
* - favicon.ico (favicon file)
*/
'/((?!api|static|favicon.ico).*)',
],
}
You cannot do this with matcher, because it only accepts simple path patterns, therefore you'll need to use conditional statement:
export function middleware(request: NextRequest) {
if (request.nextUrl.pathname.startsWith('/api/')) {
return NextResponse.next()
}
// your middleware logic
}

exported object is undefined in nodejs

I am using multer in index.js and i need to use an object which has multer storage engine in other routes. So i have exported the object but the problem is when i i try to use it in the route file its undefined.
index.js
const storage = new GridFsStorage({//some config})
const upload = multer({storage})
app.use('/posts',postRouter)
//if i use the middleware upload.single('file') here, will it affect all the routes like(posts/a,posts/b)?
exports.upload = upload
postRouter.js
const index = require('../index')
setTimeout(() => {
console.log(index.upload)
}, 1000);
console.log(index.upload)
i tried using setTimeout and its giving me the expected result but outside settimmeout its undefined.
why is this happening. what is the best way to apply the multer middleware in some other routes by exporting it from index?
the problem is GridFs is taking sometime to connect and do its work, but before that this upload object is exported . thats why above scenario occurs. any idea how to avoid that?
As GridFsStorage is asynchronous, so it need some time to init. And you can just
pass upload as param to the postRouter function.
app.use('/posts', postRouter(upload))

Split express controller into multiple files

I have a express js controller file created like this
Path: /controllers/usersController.js
// Register User
module.exports.register = function(req, res) {
...
}
// Login User
module.exports.login = function(req, res) {
...
}
// Forgot Password
module.exports.forgot_password = function(req, res) {
...
}
And I am using require() inside route file like this
Path: /routes/users.js
const usersController = require('../controllers/usersController')
router.post('/users/register', usersController.register)
router.post('/users/login', usersController.login)
router.post('/users/forgot_password', usersController.forgot_password)
This is all working fine. But my controller code is getting bigger and I want to split the userController.js into separate files so that I can have something like this
/controllers/users/index.js
/controllers/users/register.js
/controllers/users/login.js
/controllers/users/forgot_password.js
And /controllers/users/index.js needs to be the base controller which includes all these separate files. And I can simply use this index.js file into the router.
I am not sure how that is done. I tried doing module.export() method inside each separate js files and imported them inside /users/index.js file, but I am getting this error from router.
.post() requires callback functions but got a [object Undefined] not working
Note: I am not allowed to use es6 import statement :(
From whatever information I gathered from the question, you can split up the controller file by setting the module.exports to a required function in each separate file.
For example, for the /controllers/users/register.js
module.exports = function(req,res){...}
And then inside the /controllers/users/index.js
let register = require('./register.js');
router.post('/users/register', register);
And continue similarly for each controller function.

Remove Router From Express.js Route Stack

I have an Express.js project where I am allowing plugins to be loaded and unloaded at runtime. Plugins have access to the Expess.js router stack to register their paths just like a normal script would such as:
var express = require('express');
var router = express.Router();
module.exports = function(projectCoreObject) {
function Plugin() { }
// Plugin initialize called when a plugin is loaded.
Plugin.Initialize = function (done) {
// Register the router..
projectCoreObject.app.use('/', router);
};
// GET - /test
router.get('/test', function(req, res, next) {
res.send('Success!');
});
return Plugin;
};
While this all works great, I have the issue with unloading plugins removing their router from the stack.
Is there a proper way to remove a full router object from Express.js' stack at runtime? I can do individual middleware using their names but with a route like this example shows, the name is just 'router' in the stack.
I resolved this by using a named function trick to take an anonymous function and turn it into a named one. This way I can remove the router by its name then.

node.js variable scope with routes separation

my routes are defined in an external folder
./routes
here's the way i define the routes in my server.js file
app.get('/', routes.index);
app.post('/validation', register.valid);
the register.valid module, which is originally written in
./routes/validation.js
is responsible for creating a new user account and register it into a database (MongoDB).
How can i access an object from server.js in validation.js ? First, i thought declaring the object before defining my routes would resolve the case, but actually it doesn't seem to be the solution.
I'm assuming your current code already does work (that is, you receive the posted data), but you need access to another object from validation.js.
If your code works, then you probably have this line in server.js:
var register = require('./routes/validation');
And you need acess to the variable obj in the validation module. You could have a function inside the validation module:
var foo;
exports.configure = function(obj) {
foo = obj;
}
The exports mean the variable configure will be accessible to modules which "require" the validation module. This way you can do, inside the server.js module:
register.configure(obj);
app.post('/validation', register.valid);
The exact configuration of this will depend on what you are actually trying to accomplish. Sometimes, for example, it's good to have a database object stored in a global variable.
Generally in this kind of structure server.js will create the app object and then pass that to individual routes modules via a function. I do it by having each router module export a single function like this:
//routes/validation.js
function setup(app) {
app.get(....blah
app.post(....blah
}
module.exports = setup;
Then I tie that together in server.js like this:
//server.js
var express = require('express');
var app = express();
require('./routes/validation')(app);
See also my express_code_structure sample project for other code organization tips.

Categories