Skip to content

Commit c2da84e

Browse files
docs(NODE-4916, NODE-4523): update readme and upgrade guide with callback removal information (#3540)
1 parent 425dbe0 commit c2da84e

File tree

2 files changed

+130
-60
lines changed

2 files changed

+130
-60
lines changed

README.md

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22

33
The official [MongoDB](https://www.mongodb.com/) driver for Node.js.
44

5-
**Upgrading to version 4? Take a look at our [upgrade guide here](https://github.com/mongodb/node-mongodb-native/blob/HEAD/etc/notes/CHANGES_4.0.0.md)!**
5+
**Upgrading to version 5? Take a look at our [upgrade guide here](https://github.com/mongodb/node-mongodb-native/blob/HEAD/etc/notes/CHANGES_5.0.0.md)!**
66

77
## Quick Links
88

9-
| what | where |
10-
| ------------- | ------------------------------------------------------------------------------------------------------- |
11-
| documentation | [www.mongodb.com/docs/drivers/node](https://www.mongodb.com/docs/drivers/node) |
12-
| api-doc | [mongodb.github.io/node-mongodb-native](https://mongodb.github.io/node-mongodb-native) |
13-
| npm package | [www.npmjs.com/package/mongodb](https://www.npmjs.com/package/mongodb) |
14-
| source | [github.com/mongodb/node-mongodb-native](https://github.com/mongodb/node-mongodb-native) |
15-
| mongodb | [www.mongodb.com](https://www.mongodb.com) |
16-
| changelog | [HISTORY.md](https://github.com/mongodb/node-mongodb-native/blob/HEAD/HISTORY.md) |
17-
| upgrade to v4 | [etc/notes/CHANGES_4.0.0.md](https://github.com/mongodb/node-mongodb-native/blob/HEAD/etc/notes/CHANGES_4.0.0.md) |
18-
| contributing | [CONTRIBUTING.md](https://github.com/mongodb/node-mongodb-native/blob/HEAD/CONTRIBUTING.md) |
9+
| what | where |
10+
| ------------- | ----------------------------------------------------------------------------------------------------------------- |
11+
| documentation | [www.mongodb.com/docs/drivers/node](https://www.mongodb.com/docs/drivers/node) |
12+
| api-doc | [mongodb.github.io/node-mongodb-native](https://mongodb.github.io/node-mongodb-native) |
13+
| npm package | [www.npmjs.com/package/mongodb](https://www.npmjs.com/package/mongodb) |
14+
| source | [github.com/mongodb/node-mongodb-native](https://github.com/mongodb/node-mongodb-native) |
15+
| mongodb | [www.mongodb.com](https://www.mongodb.com) |
16+
| changelog | [HISTORY.md](https://github.com/mongodb/node-mongodb-native/blob/HEAD/HISTORY.md) |
17+
| upgrade to v5 | [etc/notes/CHANGES_5.0.0.md](https://github.com/mongodb/node-mongodb-native/blob/HEAD/etc/notes/CHANGES_5.0.0.md) |
18+
| contributing | [CONTRIBUTING.md](https://github.com/mongodb/node-mongodb-native/blob/HEAD/CONTRIBUTING.md) |
1919

2020
### Bugs / Feature Requests
2121

@@ -53,7 +53,7 @@ If you run into any unexpected compiler failures against our supported TypeScrip
5353

5454
## Installation
5555

56-
The recommended way to get started using the Node.js 4.x driver is by using the `npm` (Node Package Manager) to install the dependency in your project.
56+
The recommended way to get started using the Node.js 5.x driver is by using the `npm` (Node Package Manager) to install the dependency in your project.
5757

5858
After you've created your own project using `npm init`, you can run:
5959

@@ -89,7 +89,6 @@ Third party:
8989
- Snappy network compression - [snappy](https://github.com/Brooooooklyn/snappy)
9090
- AWS authentication - [@aws-sdk/credential-providers](https://github.com/aws/aws-sdk-js-v3/tree/main/packages/credential-providers)
9191

92-
9392
## Quick Start
9493

9594
This guide will show you how to set up a simple application using Node.js and MongoDB. Its scope is only how to set up the driver and perform the simple CRUD operations. For more in-depth coverage, see the [official documentation](https://docs.mongodb.com/drivers/node/).
@@ -136,18 +135,14 @@ operations using the MongoDB driver.
136135

137136
Add code to connect to the server and the database **myProject**:
138137

139-
> **NOTE:** All the examples below use async/await syntax.
140-
>
141-
> However, all async API calls support an optional callback as the final argument,
142-
> if a callback is provided a Promise will not be returned.
143-
144138
> **NOTE:** Resolving DNS Connection issues
145139
>
146140
> Node.js 18 changed the default DNS resolution ordering from always prioritizing ipv4 to the ordering
147-
> returned by the DNS provider. In some environments, this can result in `localhost` resolving to
141+
> returned by the DNS provider. In some environments, this can result in `localhost` resolving to
148142
> an ipv6 address instead of ipv4 and a consequent failure to connect to the server.
149143
>
150144
> This can be resolved by:
145+
>
151146
> - specifying the ip address family using the MongoClient `family` option (`MongoClient(<uri>, { family: 4 } )`)
152147
> - launching mongod or mongos with the ipv6 flag enabled ([--ipv6 mongod option documentation](https://www.mongodb.com/docs/manual/reference/program/mongod/#std-option-mongod.--ipv6))
153148
> - using a host of `127.0.0.1` in place of localhost
@@ -267,7 +262,7 @@ It is our recommendation to use `instanceof` checks on errors and to avoid relyi
267262
We guarantee `instanceof` checks will pass according to semver guidelines, but errors may be sub-classed or their messages may change at any time, even patch releases, as we see fit to increase the helpfulness of the errors.
268263

269264
Any new errors we add to the driver will directly extend an existing error class and no existing error will be moved to a different parent class outside of a major release.
270-
This means `instanceof` will always be able to accurately capture the errors that our driver throws (or returns in a callback).
265+
This means `instanceof` will always be able to accurately capture the errors that our driver throws.
271266

272267
```typescript
273268
const client = new MongoClient(url);

etc/notes/CHANGES_5.0.0.md

Lines changed: 115 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,74 @@ The following is a detailed collection of the changes in the major v5 release of
1818

1919
### Optional callback support migrated to `mongodb-legacy`
2020

21+
Node v5 drops support for callbacks in favor of a promise-only API. Below are some strategies for
22+
callback users to adopt driver v5 in order of most recommended to least recommended.
23+
24+
The Node driver team understands that a callback to promise migration can be a non-trivial refactor. To help inform your migration strategy, we've outlined three different approaches below.
25+
26+
#### Migrate to promise based api (recommended!)
27+
28+
The Node team strongly encourages anyone who is able to migrate from callbacks to promises to do so. Adopting the
29+
regular driver API will streamline the adoption of future driver updates, as well as provide better Typescript support
30+
than the other options outlined in this document.
31+
32+
The promise-based API is identical to the callback API except:
33+
34+
- no callback is accepted as the last argument
35+
- a promise is always returned
36+
37+
For example, with a findOne query:
38+
39+
```typescript
40+
// callback-based API
41+
collection.findOne({ name: 'john snow' }, (error, result) => {
42+
if (error) {
43+
/* do something with error */
44+
return;
45+
}
46+
47+
/* do something with result */
48+
});
49+
50+
// promise-based API
51+
collection
52+
.findOne({ name: 'john snow' })
53+
.then(() => {
54+
/* do something with result */
55+
})
56+
.catch(error => {
57+
/* do something with error */
58+
});
59+
60+
// promise-based API with async/await
61+
try {
62+
const result = await collection.findOne({ name: 'john snow' });
63+
/* do something with result */
64+
} catch (error) {
65+
/* do something with error */
66+
}
67+
```
68+
69+
#### Use the promise-based API and `util.callbackify`
70+
71+
If you only have a few callback instances where you are currently unable to adopt the promise API, we recommend using the promise API and Nodejs's `callbackify`
72+
utility to adapt the promise-based API to use callbacks.
73+
74+
**Note** Manually converting a promise-based api to a callback-based API is error prone. We strongly encourage the use of `callbackify`.
75+
76+
We recommend using callbackify with an anonymous function that has the same signature as the collection
77+
method.
78+
79+
```typescript
80+
const callbackFindOne = callbackify((query, options) => collection.findOne(query, options));
81+
82+
callbackFindOne({ name: 'john snow' }, {}, (error, result) => {
83+
// handle error or result
84+
});
85+
```
86+
87+
#### Add `mongodb-legacy` as a dependency and update imports to use `mongodb-legacy`
88+
2189
If you are a callback user and you are not ready to use promises, support for your workflow has **not** been removed.
2290
We have migrated it to a new package:
2391

@@ -26,7 +94,11 @@ We have migrated it to a new package:
2694

2795
The package wraps all of the driver's asynchronous operations that previously supported both promises and callbacks. All the wrapped APIs offer callback support via an optional callback argument alongside a Promise return value so projects with mixed usage will continue to work.
2896

29-
#### Example usage of equivalent callback and promise usage
97+
`mongodb-legacy` is intended to preserve driver v4 behavior to enable a smoother transition between
98+
driver v4 and v5. However, new features will **only** only support a promise-based
99+
API in both the driver **and** the legacy driver.
100+
101+
##### Example usage of equivalent callback and promise usage
30102

31103
After installing the package and modifying imports the following example demonstrates equivalent usages of either `async`/`await` syntax, `.then`/`.catch` chaining, or callbacks:
32104

@@ -40,10 +112,10 @@ const collection = db.collection('pets');
40112
// Legacy projects may have intermixed API usage:
41113
app.get('/endpoint_async_await', async (req, res) => {
42114
try {
43-
const result = await collection.findOne({})
115+
const result = await collection.findOne({});
44116
res.end(JSON.stringify(result));
45117
} catch (error) {
46-
res.errorHandling(error)
118+
res.errorHandling(error);
47119
}
48120
});
49121

@@ -62,45 +134,45 @@ app.get('/endpoint_callbacks', (req, res) => {
62134
});
63135
```
64136

65-
66137
### Dot Notation Typescript Support Removed By Default
67138

68139
**NOTE:** This is a **Typescript compile-time only** change. Dot notation in filters sent to MongoDB will still work the same.
69140

70-
Version 4.3.0 introduced Typescript support for dot notation in filter predicates. For example:
141+
Version 4.3.0 introduced Typescript support for dot notation in filter predicates. For example:
71142

72143
```typescript
73144
interface Schema {
74145
user: {
75-
name: string
76-
}
146+
name: string;
147+
};
77148
}
78149

79150
declare const collection: Collection<Schema>;
80151
// compiles pre-v4.3.0, fails in v4.3.0+
81-
collection.find({ 'user.name': 4 })
152+
collection.find({ 'user.name': 4 });
82153
```
83154

84155
This change caused a number of problems for users, including slow compilation times and compile errors for
85156
valid dot notation queries. While we have tried to mitigate this issue as much as possible
86157
in v4, ultimately we do not believe that this feature is fully production ready for all use cases.
87158

88-
Driver 5.0 removes type checking for dot notation in filter predicates. The preceding example will compile with
159+
Driver 5.0 removes type checking for dot notation in filter predicates. The preceding example will compile with
89160
driver v5.
90161

91162
#### Dot Notation Helper Types Exported
92163

93164
Although we removed support for type checking on dot notation filters by default, we have preserved the
94165
corresponding types in an experimental capacity.
95-
These helper types can be used for type checking. We export the `StrictUpdateFilter` and the `StrictFilter`
166+
These helper types can be used for type checking. We export the `StrictUpdateFilter` and the `StrictFilter`
96167
types for type safety in updates and finds.
97168

98169
To use one of the new types, simply create a predicate that uses dot notation and assign it the type of `StrictFilter<your schema>`.
170+
99171
```typescript
100172
interface Schema {
101173
user: {
102-
name: string
103-
}
174+
name: string;
175+
};
104176
}
105177

106178
declare const collection: Collection<Schema>;
@@ -114,8 +186,8 @@ collection.find(filterPredicate);
114186

115187
### `Collection.mapReduce()` helper removed
116188

117-
The `mapReduce` helper has been removed from the `Collection` class. The `mapReduce` operation has been
118-
deprecated in favor of the aggregation pipeline since MongoDB server version 5.0. It is recommended
189+
The `mapReduce` helper has been removed from the `Collection` class. The `mapReduce` operation has been
190+
deprecated in favor of the aggregation pipeline since MongoDB server version 5.0. It is recommended
119191
to migrate code that uses `Collection.mapReduce` to use the aggregation pipeline (see [Map-Reduce to Aggregation Pipeline](https://www.mongodb.com/docs/manual/reference/map-reduce-to-aggregation-pipeline/)).
120192

121193
If the `mapReduce` command must be used, the `Db.command()` helper can be used to run the raw
@@ -126,13 +198,17 @@ If the `mapReduce` command must be used, the `Db.command()` helper can be used t
126198
const collection = db.collection('my-collection');
127199

128200
await collection.mapReduce(
129-
function() { emit(this.user_id, 1); },
130-
function(k, vals) { return 1 },
201+
function () {
202+
emit(this.user_id, 1);
203+
},
204+
function (k, vals) {
205+
return 1;
206+
},
131207
{
132208
out: 'inline',
133209
readConcern: 'majority'
134210
}
135-
)
211+
);
136212

137213
// manually running the command using `db.command()`
138214
const command = {
@@ -141,7 +217,7 @@ const command = {
141217
reduce: 'function(k,vals) { return 1; }',
142218
out: 'inline',
143219
readConcern: 'majority'
144-
}
220+
};
145221

146222
await db.command(command);
147223
```
@@ -155,7 +231,7 @@ The `digestPassword` option has been removed from the add user helper.
155231

156232
### Removal of Internal Types from Public API
157233

158-
The following types are used internally the driver but were accidentally exported. They have now been
234+
The following types are used internally the driver but were accidentally exported. They have now been
159235
marked internal and are no longer exported.
160236

161237
- ServerSelector
@@ -176,7 +252,7 @@ For clarity the deprecated and duplicate export ObjectID has been removed. Objec
176252

177253
### `Projection` and `ProjectionOperations` Types Removed
178254

179-
Both of these types were unused but exported. These types have been removed. Please
255+
Both of these types were unused but exported. These types have been removed. Please
180256
use `Document` instead.
181257

182258
### `CommandOperationOptions.fullResponse` Option Removed
@@ -185,11 +261,11 @@ The `fullResponse` option on the `CommandOperationOptions` as unused in the driv
185261

186262
### `BulkWriteOptions.keepGoing` Option Removed
187263

188-
The `keepGoing` option on the `BulkWriteOptions` has been removed. Please use the `ordered` option instead.
264+
The `keepGoing` option on the `BulkWriteOptions` has been removed. Please use the `ordered` option instead.
189265

190266
### `WriteConcernError.err()` Removed
191267

192-
The `err()` getter on the WriteConcernError class has been removed. The `toJSON()` method can be in place
268+
The `err()` getter on the WriteConcernError class has been removed. The `toJSON()` method can be in place
193269
of `err()`.
194270

195271
### slaveOk options removed
@@ -220,7 +296,6 @@ npm install --save "snappy@^7.2.2"
220296

221297
The `.unref()` method was a no-op and has now been removed from the Db class.
222298

223-
224299
### @aws-sdk/credential-providers v3.201.0 or later and optional peerDependency
225300

226301
`@aws-sdk/credential-providers` has been added to the package.json as a peerDependency that is **optional**.
@@ -255,7 +330,7 @@ for await (const doc of cursor) {
255330
break;
256331
}
257332

258-
cursor.closed // true
333+
cursor.closed; // true
259334
```
260335

261336
### Driver now sends `1` instead of `true` for hello commands
@@ -267,14 +342,14 @@ previous `true` for spec compliance.
267342

268343
Three legacy operation helpers on the collection class have been removed:
269344

270-
| Removed API | API to migrate to |
271-
|------------------------------------------------|----------------------------------------------------|
272-
| `insert(document)` | `insertOne(document)` |
273-
| `insert(arrayOfDocuments)` | `insertMany(arrayOfDocuments)` |
274-
| `update(filter)` | `updateMany(filter)` |
275-
| `remove(filter)` | `deleteMany(filter)` |
345+
| Removed API | API to migrate to |
346+
| -------------------------- | ------------------------------ |
347+
| `insert(document)` | `insertOne(document)` |
348+
| `insert(arrayOfDocuments)` | `insertMany(arrayOfDocuments)` |
349+
| `update(filter)` | `updateMany(filter)` |
350+
| `remove(filter)` | `deleteMany(filter)` |
276351

277-
The `insert` method accepted an array of documents for multi-document inserts and a single document for single document inserts. `insertOne` should now be used for single-document inserts and `insertMany` should be used for multi-document inserts.
352+
The `insert` method accepted an array of documents for multi-document inserts and a single document for single document inserts. `insertOne` should now be used for single-document inserts and `insertMany` should be used for multi-document inserts.
278353

279354
```ts
280355
// Single document insert:
@@ -283,9 +358,9 @@ await collection.insert({ name: 'spot' });
283358
await collection.insertOne({ name: 'spot' });
284359

285360
// Multi-document insert:
286-
await collection.insert([{ name: 'fido' }, { name: 'luna' }])
361+
await collection.insert([{ name: 'fido' }, { name: 'luna' }]);
287362
// Migration:
288-
await collection.insertMany([{ name: 'fido' }, { name: 'luna' }])
363+
await collection.insertMany([{ name: 'fido' }, { name: 'luna' }]);
289364
```
290365

291366
### Removed `keepGoing` option from `BulkWriteOptions`
@@ -306,11 +381,11 @@ To access the raw result, please use `bulkWriteResult.getRawResponse()`.
306381
These can be accessed via:
307382

308383
```ts
309-
bulkWriteResult.insertedCount;
310-
bulkWriteResult.matchedCount;
311-
bulkWriteResult.modifiedCount;
312-
bulkWriteResult.deletedCount;
313-
bulkWriteResult.upsertedCount;
314-
bulkWriteResult.upsertedIds;
315-
bulkWriteResult.insertedIds;
384+
bulkWriteResult.insertedCount;
385+
bulkWriteResult.matchedCount;
386+
bulkWriteResult.modifiedCount;
387+
bulkWriteResult.deletedCount;
388+
bulkWriteResult.upsertedCount;
389+
bulkWriteResult.upsertedIds;
390+
bulkWriteResult.insertedIds;
316391
```

0 commit comments

Comments
 (0)