How to make middle ware in Nodejs with express - node.js

I'm making express router.
There is some codes like below.
But when I run node this file, it doesn't work.
I think this part make some problem.
This works in Koa but not express.
Could you give me some advice?
const printInfo = (req) => {
req.body = {
method: req.method,
path: req.path,
params: req.params,
};
};
This is the codes in a row.
const express = require('express');
const posts = express.Router();
const printInfo = (req) => {
req.body = {
method: req.method,
path: req.path,
params: req.params,
};
};
posts.get('/', printInfo);
module.exports = posts;
and
const express = require('express');
const api = express.Router();
const posts = require('./posts');
api.use('/posts', posts);
module.exports = api;
and
const express = require('express');
const app = express();
const api = require('./api/index');
app.use('/api', api);
app.listen(4000, () => {
console.log('Example app listening on port 4000!');
});

Your middleware miss the next() call and the router is not configured properly.
Follow this example, is how I always used middleware with Expressjs
middleware.js
// no need to import express/router
module.exports = (req, res, next) => {
// manipulate your body obj
req.body = {
method: req.method,
path: req.path,
params: req.params,
};
// go to the next function
next();
}
routes.js
// only import the router
const router = require('express').Router();
// function for /api/posts
router.route('/posts').post( (req, res) => {
// req.body has been manipulated from the middleware
// do anything you like and call res
res.send("...")
});
// other routes
module.exports = router;
server.js
const express = require('express');
const middleware = require('./middleware');
const routes = require('./routes');
const app = express();
// all calls to /api/* execute the middleware first
app.use('/api', middleware);
// execute the other routes functions
app.use('/api', routes);
app.listen(4000, () => {
console.log('Example app listening on port 4000!');
});

Related

Express API is not getting called from react.js

Hi everyone facing issue for API not getting called from node(express.js).
When i call it using controller file it returns status 200 with data=[] empty array and does not print in console ' [] ' but when i call the same API in the product.js(API file) it gets called
gives response as status 200 and data=hi
i have disabled app.disable("etag"); in app.js
Calling Api from react.js to Express.js API
export const getRandomProductAPI = () => Axios.get(`${url}/v1/product/getRandomProduct`);
I am having API folder in which i am reciving the request from react.js in Product.js(API file).
const express = require("express");
const router = express.Router();
const multer = require("multer");
const productController = require("../controllers/ProductController");
const storage = multer.memoryStorage({
destination: function (req, file, callBack) {
callBack(null, "");
},
});
const uploadProduct = multer({ storage }).single("productImage");
const updateProduct = multer({ storage }).single("newEditImage");
// router.get("/getRandomProduct", (req, res) => {
// res.status(200).send("hi");
// });
router.post("/add", uploadProduct, productController.addProduct);
router.get("/:category", productController.getProduct);
router.delete("/:id/:imageName", productController.deleteProduct);
router.patch("/", updateProduct, productController.updateProduct);
router.get("/Id", productController.getLatestProductId);
router.get("/getRandomProduct", productController.getRandomProduct);
module.exports = router;
API which is got called is the last one-> router.get("/getRandomProduct",roductController.getRandomProduct);
Controller Code ProductController.js
const getRandomProduct = async (req, res) => {
console.log("called");
res.status(200).send("hi");
};
module.exports = {
addProduct,
getProduct,
deleteProduct,
updateProduct,
getLatestProductId,
getRandomProduct,
};
App.js code
const express = require("express");
const morgan = require("morgan");
const helmet = require("helmet");
const cors = require("cors");
const path = require("path");
require("dotenv").config();
const middlewares = require("./middlewares");
const api = require("./api");
const app = express();
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "client/build")));
}
app.use(morgan("dev"));
app.use(helmet());
app.use(cors());
app.use(express.json());
// app.disable("etag");
app.get("/", (req, res) => {
res.json({
message: "🌎🌍🌏 Furnitures ",
});
});
app.use("/v1", api);
app.use(middlewares.notFound);
app.use(middlewares.errorHandler);
module.exports = app;

How to access my IPFS node instance from my express router

I can't seem to work out the correct approach for running a IPFS node in my express app (/services/IPFS.js), while also being able to access it within my routes (/routes/uploads.js)
/services/IPFS.js
const IPFS = require("ipfs-core");
module.exports = startNode = async (req, res, next) => {
console.log("Starting IPFS node...");
return await IPFS.create();
};
index.js
const express = require("express");
const bodyParser = require("body-parser");
const apiRouter = require("./routes/api");
const cors = require("cors");
const app = express();
const port = 4000;
const startNode = require("./services/IPFS");
app.use(cors());
app.use(bodyParser.urlencoded());
app.use(bodyParser.json());
app.use("/api/v1", apiRouter);
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
startNode();
How do I pass my IPFS instance through to /routes/upload.js so I can use ipfs.add(file) in my /upload endpoint?
Any help appreciated.
Thanks
You could define the apiRouter as a factory function and pass the startNode function to it. In your router you can then call it:
// in your index.js
// ...
app.use("/api/v1", apiRouter(startNode));
// ...
// in your apiRouter.js
const express = require('express');
const router = express.Router();
module.exports = (startNodeFn) => {
router.post('/upload', async (req, res) => {
const result = await startNodeFn.call(startNodeFn, req, res);
// handle result and do upload ...
});
// rest of routes
// ...
return router;
}

I cannot get /users json

I'm new to express and node js, I recently learned how to write API for express but at the end, I get some sort of problem which not resolved by me after several tries. I could not get a response on localhost:8080/users
src/routes/users.js
const { Router } = require("express");
const router = Router();
const getUsers = (req, res) =>
res.send(Object.values(req.context.models.users));
const getUser = (req, res) =>
res.send(req.context.models.users[req.params.userId]);
router.get("/users/", getUsers);
router.get("/users/:userId", getUser);
module.exports = router;
src/routes/index.js
const user = require("./user");
const message = require("./message");
module.exports = {
user,
message
};
src/index.js
const express = require("express");
const app = express();
// Custom Modules
const routes = require("./routes");
const models = require("./models");
// Application-Level Middleware Starts
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
req.context = {
models,
me: models.users[1]
};
console.log(req.context.models.users);
next();
});
// Used Routes
app.use("/users", routes.user);
app.use("/messages", routes.message);
// App Listning to HTTPS Module
app.listen(process.env.PORT);
You need to fix your endpoints in users.js:
router.get("/", getUsers);
router.get("/:userId", getUser);
The reason is because of app.use("/users", routes.user); in your index.js, where the endpoint for users is set. If you leave /users/ in users.js it would be localhost:8080/users/users/. Same problem might be with /messages.

json-server middleware not working as expected

using node.js/Express/json-server
I am trying to check ( and modify) the request url sent to my API json-server. I wrote as stated the following middleware in my app server.js
// API JSON-SERVER
const jsonServer = require('json-server')
const apiServer = jsonServer.create()
const apiMiddlewares = jsonServer.defaults()
apiServer.use(apiMiddlewares)
...
apiServer.use((req, res, next) => {
console.log('REQUEST: ', req)
next() // Continue to JSON Server Router
})
...
apiRouter = jsonServer.router(path.join(__dirname, '..', 'server', 'db-dev.json'))
app.use('/api', apiRouter)
but I never get the request displayed
where am I wrong ?
I looked here
https://github.com/typicode/json-server/issues/253
and it seems to me that you never want to instantiate the jsonServer, but only use the router. Since you are using the express server, you should attach the middleware to that.
const express = require('express')
const jsonServer = require('json-server')
const app = express()
app.use((req, res, next) => {
console.log('REQUEST: ', req)
next() // Continue to JSON Server Router
})
app.use('/api', jsonServer.router(path.join(__dirname, '..', 'server', 'db-dev.json')))

Express Middleware Issue

On routes/index.js it works fine if I leave the module.exports = routes;
But If I change it to the following to allow multiple files then I get a middleware error:
module.exports = {
routes
};
var app = express();
const routes = require('./routes');
const port = process.env.PORT || 3000;
app.use(bodyParser.json());
app.use('/', routes);
app.get('/', (req, res) => {
res.send('Please visit: http://domain.com');
}, (err) => {
res.send(err);
});
//routes/index.js
const routes = require('./MainRoutes');
module.exports = routes;
//routes/Main Routes.js
const routes = require('express').Router();
routes.post('/main', (res, req) => {
//code here works
});
module.exports = routes;
The error is: Router.use() requires middleware function but got a ' + gettype(fn));
MainRoutes.js exports the express router object, which middleware will understand just fine if you do
module.exports = routes; // routes/index.js
However, when you do
module.exports = {
routes
};
You are now nesting that router object in another object, which middleware can't understand.
In your main server file you can do
const {routes} = require('./routes');
to get the router object properly.
Modify the routes/index.js as:
const routes = require('express').Router();
routes.use('/main', require('./MainRoutes'));
// Put other route paths here
// eg. routes.use('/other', require('./OtherRoutes'))
module.exports = routes;
Modify the Main Routes.js as:
const routes = require('express').Router();
routes.post('/', (res, req) => {
// route controller code here
});
module.exports = routes;
Hope this helps you.

Resources