Context
What do we want out of a new Go Driver API?
Merge bulk write types.
Currently there's a lot of duplication between the bulk write APIs. That creates a significantly larger API surface area than is necessary.
Merge options package into mongo.
The options package is awkwardly named and has a huge surface area. Moving options into the mongo package may allow us to significantly reduce the API surface area if we can use generics to merge similar CRUD options (e.g. SetComment). Either way, the ergonomics of setting optional behaviors would be much better if it was in the mongo package.
This is already described by GODRIVER-3500, but should be considered as a part of a simplified mongo API.
We should also consider migrating to functional options to align with common patterns in other Go libraries:
client, _ := mongo.Connect(
WithURI("mongodb://localhost:27017"),
WithMinPoolSize(5),
)
We should also consider moving the options for CRUD methods to builder methods on the CRUD operation:
coll.InsertOne(context.TODO(), mongo.NewInsertOne(document).BypassDocumentValidation(true))
Offer a Run API for running individual ops, plus helper CRUD methods.
The current CRUD API is confusing to use because there's a lot of overlap between the different methods. A more ergonomic API would be more like Go's net/http package, which offers a Client.Do method plus high-level convenience APIs.
E.g.
type Operation[T any] interface { operation() Result() T } // Run can run any single operation. func Run[T any, U Operation[T]](context.Context, *Collection, op Operation) (T, error) // Still provide CRUD Collection methods for convenience. func (*Collection) InsertOne(...) (InsertOneResult, error)
Which would be used like:
res, err := Run(context.TODO(), coll, NewInsertOne().SetDocument(...))
Note that Run is a function, not a method, which would be required for using generic result types.
Note that we may want to make the Run API unexported to start, then evaluate if we want to export it.
Experimental API
We should consider renaming the "x" package to "exp". In the Go community "x" means "extended" and "exp" means "experimental".
Definition of done
What must be done to consider the task complete?
Pitfalls
- Do the above requirements result in a more ergonomic API?
- What issues do users actually have with the mongo/options APIs?
- Still none of this solves the bson.D usability issues.