0

I am building a fastify application with mongodb. I've created this package.json file with a script to run mongo.

{
    "dependencies": {
        "@fastify/mongodb": "5.0.0",
        "fastify": "4.11.0"
    },
    "scripts": {
        "start": "node server.js",
        "start-mongo": "docker run -d --name my-mongo -p 27017:27017 mongo",
    }
}

And with npm run start-mongo I run mongo exposing port 27017. Then, ... this is fastify part.

const fastify = require('fastify')({logger: true})

fastify.register(require('@fastify/mongodb'), {
    forceClose: true,
    url: 'mongodb://localhost:27017/library'
})

fastify.get('/books', async(request, reply) => {
    const books = await fastify.mongo.db
        .collection('books')
        .find()

    reply.send(books)
});

fastify.post('/books', async(request, reply) => {
    const result = await fastify
        .mongo.db
        .collection('books')
        .insertOne(request.body)

    reply.send({
        message: 'book added',
        id: result.insertId
    })
})

GET /books:

{"_events":{},"_eventsCount":0}

POST /books

curl -H 'Content-Type: application/json' -X POST http://localhost:3000/books -d '{"message":"prova"}'

returns

{"message":"book added"}

It is strange because response should contain also id. But it doesnt.

    reply.send({
        message: 'book added',
        id: result.insertId
    })

This means that

    const result = await fastify
        .mongo.db
        .collection('books')
        .insertOne(request.body)

doesnt store the book. Any error is displayed and GET always return:

{"_events":{},"_eventsCount":0}

What's wrong?

--

I've also created mongo with docker-compose:

version: '3.1'
services:
  mongo:
    image: mongo
    restart: always
    ports:
      - 27017:27017
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: example

but it returns:

{
  statusCode: 500,
  code: '13',
  error: 'Internal Server Error',
  message: 'command insert requires authentication'
}
{
  statusCode: 500,
  code: '13',
  error: 'Internal Server Error',
  message: 'command find requires authentication'
}

I updated code from

fastify.register(require('@fastify/mongodb'), {
    forceClose: true,
    url: 'mongodb://localhost:27017/library'
})

to

fastify.register(require('@fastify/mongodb'), {
    forceClose: true,
    url: 'mongodb://root:example@localhost:27017/library'
})

but returns:

(node:86146) UnhandledPromiseRejectionWarning: MongoServerError: Authentication failed.
    at Connection.onMessage (/Users/simonegentili/Development/github.com/sensorario/youtube.poliglotta/node_modules/mongodb/lib/cmap/connection.js:227:30)
    at MessageStream.<anonymous> (/Users/simonegentili/Development/github.com/sensorario/youtube.poliglotta/node_modules/mongodb/lib/cmap/connection.js:60:60)
    at MessageStream.emit (events.js:375:28)
    at processIncomingData (/Users/simonegentili/Development/github.com/sensorario/youtube.poliglotta/node_modules/mongodb/lib/cmap/message_stream.js:125:16)
    at MessageStream._write (/Users/simonegentili/Development/github.com/sensorario/youtube.poliglotta/node_modules/mongodb/lib/cmap/message_stream.js:33:9)
    at writeOrBuffer (internal/streams/writable.js:358:12)
    at MessageStream.Writable.write (internal/streams/writable.js:303:10)
    at Socket.ondata (internal/streams/readable.js:726:22)
    at Socket.emit (events.js:375:28)
    at addChunk (internal/streams/readable.js:290:12)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:86146) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:86146) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Why "Authentication failed"?

sensorario
  • 20,262
  • 30
  • 97
  • 159

1 Answers1

1

You need to:

  1. update fastify mongo to v6 that supports fastify v4
  2. The GET returns a cursor so change it to fastify.mongo.db.collection('books').find().toArray()
  3. To get back the inserted id you need to change from inserted to insertedId
  4. to set the MongoDB password duplicated question or you need to set the database property - code below updated:
  • note the plugin configuration
  • note the usage fastify.mongo.db.collection

Quick and dirty copy-paste:

const fastify = require('fastify')({ logger: !true })

fastify.register(require('@fastify/mongodb'), {
  forceClose: true,
  url: 'mongodb://root:example@localhost:27017',
  database: 'library'
})

fastify.get('/books', async (request, reply) => {
  const books = await fastify.mongo.db.collection('books').find().toArray()

  reply.send(books)
})

fastify.post('/books', async (request, reply) => {
  const result = await fastify
    .mongo.db
    .collection('books')
    .insertOne(request.body)

  reply.send({
    message: 'book added',
    id: result.insertedId
  })
})

async function start () {
  const done = await fastify.inject({
    method: 'POST',
    url: '/books',
    body: { asd: 'foo' }
  })
  console.log(done.json())

  const res = await fastify.inject('/books')
  console.log(res.json())

  fastify.close()
}

start()


Manuel Spigolon
  • 11,003
  • 5
  • 50
  • 73