Nodejs bodyParser.raw on one route - node.js

I have the following in my index.js:
app.use(bodyParser.json());
But Stripe webhooks want this:
Match the raw body to content type application/json
If I change my index.js to the following:
app.use(bodyParser.raw({type: 'application/json'}));
It works fine. But all my other API routes will not work anymore. Here is my route:
router.route('/stripe-events')
.post(odoraCtrl.stripeEvents)
How can I change to the raw body for only this api route?

You can access to both at the same time by doing this:
app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf
}
}))
Now the raw body is available on req.rawBody and the JSON parsed data is available on req.body.

Divide them into two routers '/api' and '/stripe-events' and indicate bodyParser.json() only for the first one:
stripeEvents.js
const express = require('express')
const router = express.Router()
...
router.route('/stripe-events')
.post(odoraCtrl.stripeEvents)
module.exports = router
api.js
const express = require('express')
const router = express.Router()
...
router.route('/resource1')
.post(addResource1)
router.route('/resource2')
.post(addResource2)
module.exports = router
const stripeEventsRouter = require('./routers/stripeEvents';
const apiRouter = require('./routers/api';
apiRouter.use(bodyParser.json());
stripeEventsRouter.use(bodyParser.raw({type: 'application/json'}));
app.use('/api', stripeEventsRouter);
app.use('/api', apiRouter);

Related

Route does not exist on the browser but it works fine on the postman

Okay so i just started building an api using Node. Normally, before i even start, i test it in the postman using dummy data to make sure all the routes are working fine but i never tested it on the browser until today. It brings out the dummy data all fine in the postman but when I put in the same route i used in the postman on the browser tab, it just brings out my custom error message "Route does not exist". Why is this happening?
This is my routes/auth.js
const express = require('express')
const router = express.Router()
const {upload} = require('../utils/multer')
const { register, login } = require('../controllers/auth')
router.post('/register', upload.single('picture'), register)
router.post('/login', login)
module.exports = router
This is my controllers/auth.js:
const register = async (req, res) => {
res.send('register')
}
const login = async (req, res) => {
res.send('login')
}
module.exports = {register, login}
This is my app.js:
require('dotenv').config()
require('express-async-errors');
const bodyParser = require('body-parser')
const cors = require('cors')
const multer = require('multer')
const helmet = require('helmet') //helps you secure your Express apps by setting various HTTP headers.
const morgan = require('morgan')
const path = require('path')
const express = require('express');
const app = express();
/* CONFIGURATIONS */
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
app.use(morgan("common"));
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(express.urlencoded({ limit: "30mb", extended: true }));
app.use("/assets", express.static(path.join(__dirname, "public/assets")));
//routers
const authRouter = require('./routes/auth')
// error handlers
const notFoundMiddleware = require('./middleware/not-found');
const errorHandlerMiddleware = require('./middleware/error-handler');
//middleware
app.use(express.json());
app.use(cors());
//routes
app.use('/api/v1/auth', authRouter)
//errors
app.use(notFoundMiddleware);
app.use(errorHandlerMiddleware);
//database
const connectDB = require('./db/connect');
const port = process.env.PORT || 5000;
const start = async () => {
try {
await connectDB(process.env.MONGO_URI);
app.listen(port, () =>
console.log(`Server is listening on port ${port}...`)
);
} catch (error) {
console.log(error);
}
};
start();
Please note that i do not understand what most of these configurations do, not very well anyways. i have tried to remove them though but the problem was still there.
I am assuming you are trying to access /login or /register route from browser search bar something like this http://host:port/login. With this browser will send GET /login request but /login is a POST method route that is the reason you are getting Route not found
When you send request from your browser then by default it will send GET request and your app is not handling GET requests.
You are handling POST requests for /register and /login routes.

Express post request gives {}

So, when i make a Post request to the ExpressJS api with postman (localhost:8080?test=test), i should get this from the api: {test: test} or something right? But i get this: {}.
Heres my code:
Api:
const express = require('express');
const http = require('http');
const path = require('path');
const app = express();
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
app.use(cookieParser())
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json())
app.use(express.static(__dirname + '../../../src/'));
app.get('/*', (req,res) => res.sendFile(path.join(__dirname)));
const server = http.createServer(app);
server.listen(port,() => {
console.log('Running...');
})
app.post('/', function(req,res){
let data = JSON.stringify(req.body);
console.log(data);
res.send(data)
})
Can you help me?
Edit:
Printscreen
Inside post endpoint you are console logging req.body which is actually {}. According to the endpoint you are receiving data as query params. Therefore you have to use req.query instead of req.body to capture the data.

POST req body return empty array

i have a problem when POST some data in POSTMAN my problem is during "post" method /auth/login req.body return empty array.
Postman return empty object only if i use POST method with use form-data, if i change to xxx-www-form-urlencoded whatever works fine. I wanna know why it works so
const express = require('express');
const mongoose = require('mongoose');
const app = express();
require('dotenv').config();
const port = process.env.PORT || 5000;
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use("/static", express.static(__dirname + "/assets"))
app.post('/auth/login', (req, res) => {
res.status(200).json(req.body)
})
mongoose.connect("mongodb://localhost:27017")
.then(() => {
app.listen(port, () => {
console.log('port' + port)
})
})
I'm assuming you mean application/x-www-form-urlencoded instead of xxx-www-form-urlencoded and you mean multipart/form-data instead of form-data.
These 2 content-types are completely different encodings. When you called:
app.use(express.urlencoded({ extended: true }));
You added a middleware that can parse application/x-www-form-urlencoded, but that does not mean it automatically parses other formats too. It's only for that format, just like express.json() is only for the application/json format.
I solved this, i just created multer in my controller and it work how i wanted
const express = require('express');
const router = express.Router();
const { getUsers, createNewUser } = require('../controllers/newUser')
const path = require('path');
const multer = require('multer');
const upload = multer();
router.get('/', getUsers)
router.get('/:id', (req, res) => res.send('get single user'))
router.post('/', upload.none(), createNewUser)
module.exports = router;

POST request body not available in Express middleware 'req'

I have an odd query that has really stumped me.
I have created this Express middleware:
const express = require('express')
const bodyParser = require('body-parser')
var router = express.Router()
router.use(bodyParser.urlencoded({ extended: false }))
router.use(bodyParser.json())
app.use(router)
router.use((req, res, next) => {
console.log(req.body)
})
router.post((req, res) => {
...
})
Whever I try to log the body in the router.post, it logs the correct body. However, when I try to log it in the router.use (as shown above), it only returns an empty object. Any thoughts of how I can get the body in middleware? Thanks!
Only isssue I see according to the official documentation is that you've to set the router to the app after declaring all the middlewares as said in the below attached image,
which means you code should be changed to
const express = require('express')
const bodyParser = require('body-parser')
var router = express.Router()
router.use(bodyParser.urlencoded({ extended: false }))
router.use(bodyParser.json())
router.use((req, res, next) => {
console.log(req.body)
})
router.post((req, res) => {
...
})
//setting the router as a middleware after declaring all the routes and middleware functions.
app.use(router)
References:
Express Routing
Express Router API

body parser logging empty object in express router

for some reason I can see my req.body in my express server on my route
req body is [Object: null prototype] { '{"password":"xxxxxxxx"}': '' }
but when I log req.body.password (the object key) I get
req body is undefined
here's my index router for reference in my express app
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser')
const path = require('path');
/* GET adminPanel. */
router.post('/authenticate', function(req, res, next) {
console.log('req body is',req.body.password)
res.send("passconfirmed");
});
module.exports = router;
To access the content of the body, Parse incoming request bodies in a middleware before your handlers, available under the req.body property.
You need to install a body-parser package.
npm i body-parser --save
Now import body-parser in your project.
It should be called before your defined route functions.
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser')
const path = require('path');
app.use(bodyParser.json());
app.use(bodyparser.urlencoded({ extended : true }));
/* GET adminPanel. */
router.post('/authenticate', function(req, res, next) {
console.log('req body is',req.body.password)
res.send("passconfirmed");
});
module.exports = router;
If you're using body-parser
You have to enable the body parser to work, before using parsed data in you routes.
In your main module where you import all your libs, you need to declare express to use body-parser middleware.
const express = require('express')
const bodyparser = require('body-parser')
const app = express()
app.use(bodyparser.json())
app.use(bodyparser.urlencoded({ extended : true }))
...
//here comes your routes
After including the bodyparser middleware you can use parsed data in your routes.
Notice that if you're using express version >= 4.16, body parser comes bundled with express. You just have to use change your code to:
const express = require('express')
const app = express()
app.use(express.json()); //this line activates the bodyparser middleware
app.use(express.urlencoded({ extended: true }));
Doing so you can safely remove body-parser package.

Resources