Skip to content

Commit 80f50cf

Browse files
committed
docs: add shared schema docs
Fix #14082
1 parent 2ecc7ed commit 80f50cf

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

docs/guides.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ integrating Mongoose with external tools and frameworks.
3030
* [Custom Casting For Built-in Types](tutorials/custom-casting.html)
3131
* [Custom SchemaTypes](customschematypes.html)
3232
* [Advanced Schemas](advanced_schemas.html)
33+
* [Sharing Schemas Between Mongoose Projects](shared-schemas.html)
3334

3435
## Integrations
3536

docs/shared-schemas.md

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,73 @@
1-
# Sharing Schemas Between Mongoose Projects
1+
# Sharing Schemas Between Mongoose Projects
2+
3+
In larger organizations, it is common to have a project that contains schemas which are shared between multiple projects.
4+
For example, suppose your company has an `@initech/shared-schemas` private npm package, and `npm list` looks like the following:
5+
6+
```sh
7+
@initech/web-app1@1.0.0
8+
├── @initech/shared-schemas@1.0.0
9+
├── mongoose@8.0.1
10+
```
11+
12+
In the above output, `@initech/web-app1` is a *client project* and `@initech/shared-schemas` is the *shared library*.
13+
14+
## Put Mongoose as a Peer Dependency
15+
16+
First, and most importantly, we recommend that `@initech/shared-schemas` list Mongoose in [your shared-schema's `peerDependencies`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#peerdependencies), **not** as a top-level dependency.
17+
For example, `@initech/shared-schemas`'s `package.json` should look like the following.
18+
19+
```javascript
20+
{
21+
"name": "@initech/shared-schemas",
22+
"peerDependencies": {
23+
"mongoose": "8.x"
24+
}
25+
}
26+
```
27+
28+
We recommend this approach for the following reasons:
29+
30+
1. Easier to upgrade. For example, suppose `@initech/shared-schemas` has a dependency on Mongoose 8, and `@initech/web-app1` works fine with Mongoose 8; but `@initech/web-app2` cannot upgrade from Mongoose 7. Peer dependencies makes it easier for the projects that rely on your shared schemas to determine which version of Mongoose they want, without risking having conflicting versions of the Mongoose module.
31+
2. Reduce risk of Mongoose module duplicates. Using Mongoose schemas and models from one version of Mongoose with another version is not supported.
32+
33+
## Export Schemas, Not Models
34+
35+
We recommend that `@initech/shared-schemas` export Mongoose schemas, **not** models.
36+
This approach is more flexible and allows client projects to instantiate models using their preferred patterns.
37+
In particular, if `@initech/shared-schemas` exports a model that is registered using `mongoose.model()`, there is no way to transfer that model to a different connection.
38+
39+
```javascript
40+
// `userSchema.js` in `@initech/shared-schemas`
41+
const userSchema = new mongoose.Schema({ name: String });
42+
43+
// Do this:
44+
module.exports = userSchema;
45+
46+
// Not this:
47+
module.exports = mongoose.model('User', userSchema);
48+
```
49+
50+
## Workaround: Export a POJO
51+
52+
Sometimes, existing shared libraries don't follow the above best practices.
53+
If you find yourself with a shared library that depends on an old version of Mongoose, a helpful workaround is to export a [POJO](https://masteringjs.io/tutorials/fundamentals/pojo) rather than a schema or model.
54+
This will remove any conflicts between the shared library's version of Mongoose and the client project's version of Mongoose.
55+
56+
```javascript
57+
// Replace this:
58+
module.exports = new mongoose.Schema({ name: String });
59+
60+
// With this:
61+
module.exports = { name: String };
62+
```
63+
64+
And update your client project to do the following:
65+
66+
```javascript
67+
// Replace this:
68+
const { userSchema } = require('@initech/shared-schemas');
69+
70+
// With this:
71+
const { userSchemaDefinition } = require('@initech/shared-schemas');
72+
const userSchema = new mongoose.Schema(userSchemaDefinition);
73+
```

docs/source/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ docs['docs/lodash.md'] = { title: 'Using Mongoose with Lodash', markdown: true }
100100
docs['docs/incompatible_packages.md'] = { title: 'Known Incompatible npm Packages', markdown: true };
101101
docs['docs/check-version.md'] = { title: 'How to Check Your Mongoose Version', markdown: true };
102102
docs['docs/version-support.md'] = { title: 'Version Support', markdown: true };
103+
docs['docs/shared-schemas.md'] = { title: 'Sharing Schemas Between Mongoose Projects', markdown: true };
103104

104105
for (const props of Object.values(docs)) {
105106
props.jobs = jobs;

0 commit comments

Comments
 (0)