mongodbexpressnode-mongodb-native

No post request body with MongoDB Native NodeJS driver


ExpressJS / MongoDB Native NodeJS Driver

I'm seriously confused why this post request keeps coming back with no request body. The Mongo method insertOne is technically being run, but theres just no data there, so it just enters null values. The get request work fine.

app.js

import express from 'express';
import cors from 'cors';
import rateLimit from 'express-rate-limit';
import helmet from 'helmet';
import mongoSanitize from 'express-mongo-sanitize';
import xss from 'xss-clean';
import hpp from 'hpp';

const app = express();

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
});

app.use(cors());
app.use(helmet());
app.use('/api', limiter);
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(mongoSanitize());
app.use(xss());
app.use(hpp());

app.get('/', (req, res) => {
  res.send('Hello World!!1 🤓');
});

export default app;

server.js

import mongodb from 'mongodb';

import app from './app.js';
import routes from './routes.js';

const port = process.env.PORT || 5000;
const uri = 'mongodb://127.0.0.1:27017/simon';
const client = new mongodb.MongoClient(uri, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

app.listen(port, () =>
  console.log(`✅ Server running on port ${port}... connecting to MongoDB...`)
);

(async function () {
  try {
    await client.connect();
    const db = client.db('simon');
    await db.command({ ping: 1 });
    console.log('✅ MongoDB connected');
    routes.forEach((route) => {
      route(app, db);
    });
  } catch (error) {
    console.error('❌ MongoDB connection error:', error.message);
  }
})();

routes.js

function getScores(app, db) {
  app.get('/api', async (req, res) => {
    try {
      const response = await db.collection('highScores').find().limit(5).toArray();
      console.log('response:', response);
      res.status(200).json(response);
    } catch (error) {
      console.error('Error getting scores:', error.message);
    }
  });
}

function addScore(app, db) {
  app.post('/api', async (req, res) => {
    const { name, score } = req.body;

    console.log('req.body:', req.body); // this always returns: {}

    try {
      const result = await db.collection('highScores').insertOne({ name, score });
      res.status(200).json(result);
    } catch (error) {
      console.error('Error adding score:', error.message);
    }
  });
}

export default [getScores, addScore];

example result of the post request

{
    "result": {
        "n": 1,
        "ok": 1
    },
    "connection": {
        "_events": {},
        "_eventsCount": 4,
        "id": 1,
        "address": "127.0.0.1:27017",
        "bson": {},
        "socketTimeout": 0,
        "host": "127.0.0.1",
        "port": 27017,
        "monitorCommands": false,
        "closed": false,
        "destroyed": false,
        "lastIsMasterMS": 1
    },
    "ops": [
        {
            "_id": "610f70754792504433bba4e4"   // <- only the auto generated id
        }
    ],
    "insertedCount": 1,
    "insertedId": "610f70754792504433bba4e4",
    "n": 1,
    "ok": 1
}

what im entering in postman what im entering in postman

the newly created object in mongodb

{
  _id: ObjectId('610f70754792504433bba4e4')
  name: null
  score: null
}

Solution

  • You request must contain the header Content-Type: application/json. And the attribute names in the JSON body must be quoted:

    {"name": "Jef", "score": 42}