deno: MongoDB Node.js Driver doesn't work when connecting to MongoDB Atlas from Deno
Potentially related to issue #15824, but the mongodb driver cannot be used directly via Deno when targeting a MongoDB Atlas cluster. This was reported at NODE-4782 however it doesn’t appear to be an issue with the Node driver itself.
// file: main.ts
import { MongoClient } from "mongodb"
const URI = "mongodb+srv://user:pass@cluster0.abcde.mongodb.net/test"
const client = new MongoClient(URI)
async function main() {
console.log('connecting')
await client.connect()
console.log('connected')
const collection = client.db('test_db').collection('test_collection')
await collection.deleteMany({})
await collection.insertOne({ a: 2.3 })
var results = await collection.count({ a: 2.3 })
console.log(`found ${results}`)
process.exit(1)
}
main()
For example, when running the preceding using npx ts-node main.ts the script will connect to Atlas, authenticate/authorize, clear the collection, insert a new doc and execute a count.
connecting
connected
found 1
To make this run with Deno the script was updated as follows:
// file: main.ts
import { MongoClient } from 'npm:mongodb' // updated for Deno
const URI = "mongodb+srv://user:pass@cluster0.abcde.mongodb.net/test"
const client = new MongoClient(URI)
async function main() {
console.log('connecting')
await client.connect()
console.log('connected')
const collection = client.db('test_db').collection('test_collection')
await collection.deleteMany({})
await collection.insertOne({ a: 2.3 })
var results = await collection.count({ a: 2.3 })
console.log(`found ${results}`)
process.exit(1)
}
main()
When the above script variation is run using deno run --unstable --allow-all main.ts it will fail with the following error as it doesn’t appear to be able to resolve a DNS Seed List Connection String:
connecting
error: Uncaught MongoAPIError: Server record does not share hostname with parent URI
at resolveSRVRecord (file:///Users/alex/Library/Caches/deno/npm/registry.npmjs.org/mongodb/4.11.0/lib/connection_string.js:62:19)
at async file:///Users/alex/Library/Caches/deno/npm/registry.npmjs.org/mongodb/4.11.0/lib/mongo_client.js:120:31
at async main (file:///Users/alex/temp/main.ts:17:3)
Changing the URI constant to use a Standard Connection String of mongodb://user:pass@cluster0-shard-00-00.abcde.mongodb.net:27017,cluster0-shard-00-01.abcde.mongodb.net:27017,cluster0-shard-00-02.abcde.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true&w=majority and re-running results in the operation just timing out:
connecting
error: Uncaught MongoServerSelectionError: connection timed out
at Timeout.<anonymous> (file:///Users/alex/Library/Caches/deno/npm/registry.npmjs.org/mongodb/4.11.0/lib/sdam/topology.js:293:38)
at https://deno.land/std@0.162.0/node/timers.ts:21:15
at Object.action (deno:ext/web/02_timers.js:147:13)
at handleTimerMacrotask (deno:ext/web/02_timers.js:64:12)
Note this was tested with:
deno 1.27.2 (release, x86_64-apple-darwin)
v8 10.8.168.4
typescript 4.8.3
Steps to Reproduce
- Sign up for a free M0 Atlas Cluster
- Get a Connection String (pick an older version of any driver to get the
mongodb://version instead ofmongodb+srv://) - Update the
URIconstant with your connection string deno run --unstable --allow-all main.ts
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 18
- Comments: 28 (2 by maintainers)
Thanks for investigating @hazelnutcloud, @crowlKats is looking into this issue and it should be fixed in the coming days.
It now started connecting to MongoDB with
npm:mongodb@5.6.0from Atlas uri. I can use CRUD operations but it throws error after a few minutesFYI https://github.com/mongodb/node-mongodb-native/releases/tag/v5.3.0 has been released, which includes the fixes to SRV resolution that were affecting Deno. There may still be an opportunity to address this behavior in Deno directly, but for now the MongoDB driver should work 😃
I think I have figured out the source of this problem. When connecting with the
mongodb+srvprotocol, the node.js mongo driver compares the resolved SRV records against the parent domain.To do that, it calls
resolveSrv()function imported from node’sdnsmodule. Calling this API from Deno results in trailing dots in thenamefield of the objects in the array returned by theresolveSrv()function meanwhile running it node produces no trailing dotsHere’s the code I used to test this:
And here are the outputs when running in Deno:
in node:
I edited all the hostnames displayed there to hide some info but that’s what it should look like.
@bartlomieju @crowlKats
Interesting development. Using a DNS Seed List in the URI appears to work correctly in the latest Deno:
@eikooc you beat me to it 😃 The MongoDB Node Driver team addressed this with https://github.com/mongodb/node-mongodb-native/commit/051b8615ac0ebebb8c07d7a661bf1ab4f99cf4b2, which will be included in the next release of the driver.
I’ll close this issue out once the release is made 😃
@hazelnutcloud from a MongoDB Driver POV a bug for this was reported previously (see NODE-5042) which we’re hoping to get sorted out soon.
It’s really helpful to see further confirmation that resolving this bug should improve the Deno experience using MongoDB!
I believe this has been fixed in v1.37 https://github.com/denoland/deno/pull/20314. Right now it is possible to update by running
deno upgrade --canaryJust chiming in with an update. The ticket over at MongoDB’s Jira is marked as done with fix version v5.3.0.
https://jira.mongodb.org/browse/NODE-5042
To get a non-SRV connection string, click the Connect button in the Atlas UI, choose the
Node.jsdriver, and then select2.2.12 or later. The connection string supplied for this version will work with all later versions of the Node.js driver and should also work with Deno.