If you have logged into MongoDB Atlas recently - and you should, the entry-level tier is free! - you may have noticed a strange new syntax on 3.6 connection strings.

#MongoDB Seed Lists What is this mongodb+srv syntax? Well, in MongoDB 3.6 we introduced the concept of a seed list that is specified using DNS records, specifically SRV and TXT records. You will recall from using replica sets with MongoDB that the client must specify at least one replica set member (and may specify several of them) when connecting. This allows a client to connect to a replica set even if one of the nodes that the client specifies is unavailable. You can see an example of this URL on a 3.4 cluster connection string: Note that without the SRV record configuration we must list several nodes (in the case of Atlas we always include all the cluster members, though this is not required). We also have to specify the ssl and replicaSet options. With the 3.4 or earlier driver, we have to specify all the options on the command line using the MongoDB URI syntax. The use of SRV records eliminates the requirement for every client to pass in a complete set of state information for the cluster. Instead, a single SRV record identifies all the nodes associated with the cluster (and their port numbers) and an associated TXT record defines the options for the URI.

#Reading SRV and TXT Records We can see how this works in practice on a MongoDB Atlas cluster with a simple Python script. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import srvlookup import sys import dns.resolver host = None if len(sys.argv) > 1 : host = sys.argv[ 1 ] if host : services = srvlookup.lookup( "mongodb" , domain=host) for i in services: print( "%s:%i" % (i.hostname, i.port)) for txtrecord in dns.resolver.query(host, 'TXT' ): print( "%s: %s" % ( host, txtrecord)) else : print( "No host specified" ) copy code We can run this script using the node specified in the 3.6 connection string as a parameter. 1 2 3 4 5 6 7 $ python mongodb_srv_records.py freeclusterjd-ffp4c.mongodb.net freeclusterjd-shard-00-00-ffp4c.mongodb.net:27017 freeclusterjd-shard-00-01-ffp4c.mongodb.net:27017 freeclusterjd-shard-00-02-ffp4c.mongodb.net:27017 freeclusterjd-ffp4c.mongodb.net: "authSource=admin&replicaSet=FreeClusterJD-shard-0" $ copy code You can also do this lookup with nslookup: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 JD10Gen-old:~ jdrumgoole$ nslookup > set type =SRV > \_mongodb._tcp.rs.joedrumgoole.com Server: 10.65.141.1 Address: 10.65.141.1 Non-authoritative answer: \_mongodb._tcp.rs.joedrumgoole.com service = 0 0 27022 rs1.joedrumgoole.com. \_mongodb._tcp.rs.joedrumgoole.com service = 0 0 27022 rs2.joedrumgoole.com. \_mongodb._tcp.rs.joedrumgoole.com service = 0 0 27022 rs3.joedrumgoole.com. Authoritative answers can be found from: > set type =TXT > rs.joedrumgoole.com Server: 10.65.141.1 Address: 10.65.141.1 Non-authoritative answer: rs.joedrumgoole.com text = "authSource=admin&replicaSet=srvdemo" copy code You can see how this could be used to construct a 3.4 style connection string by comparing it with the 3.4 connection string above. As you can see, the complexity of the cluster and its configuration parameters are stored in the DNS server and hidden from the end user. If a node's IP address or name changes or we want to change the replica set name, this can all now be done completely transparently from the client's perspective. We can also add and remove nodes from a cluster without impacting clients. So now whenever you see mongodb+srv you know you are expecting a SRV and TXT record to deliver the client connection string.