Skip to content

Commit 2f18e93

Browse files
committed
WIP: release notes for 9.0.0
1 parent 43259ac commit 2f18e93

File tree

4 files changed

+248
-5
lines changed

4 files changed

+248
-5
lines changed

.github/FUNDING.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# These are supported funding model platforms
2+
3+
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4+
patreon: # Replace with a single Patreon username
5+
open_collective: graphql-compose
6+
ko_fi: # Replace with a single Ko-fi username
7+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9+
liberapay: # Replace with a single Liberapay username
10+
issuehunt: # Replace with a single IssueHunt username
11+
otechie: # Replace with a single Otechie username
12+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

.markdownlint.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
"ol-prefix": false,
88
"first-line-h1": false,
99
"first-heading-h1": false,
10-
"no-bare-urls": false
10+
"no-bare-urls": false,
11+
"blanks-around-lists": false
1112
}

.vscode/settings.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
{
2-
"eslint.validate": ["javascript"],
32
"javascript.validate.enable": false,
4-
"javascript.autoClosingTags": false,
5-
"eslint.autoFixOnSave": true,
3+
"typescript.tsdk": "node_modules/typescript/lib",
4+
"editor.formatOnSave": false,
5+
"javascript.format.enable": false,
6+
"typescript.format.enable": false,
67
"editor.codeActionsOnSave": {
78
"source.fixAll.eslint": true
8-
}
9+
},
910
}

docs/releases/9.0.0.md

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
# Release notes graphql-compose-mongoose v9.0.0
2+
3+
<!-- TOC depthFrom:2 -->
4+
5+
- [What's new?](#whats-new)
6+
- [🛑 resolver creation (factory)](#🛑-resolver-creation-factory)
7+
- [🛑 error handling (payload.error, mongoose validation)](#🛑-error-handling-payloaderror-mongoose-validation)
8+
- [Improvements](#improvements)
9+
- [Now `_id` field can be of any type (Int, String, Object)](#now-_id-field-can-be-of-any-type-int-string-object)
10+
- [🛑 recursive `filter._operators`](#🛑-recursive-filter_operators)
11+
- [🛑 better alias & projection support for nested embedded documents](#🛑-better-alias--projection-support-for-nested-embedded-documents)
12+
- [🛑 typescript improvements for resolvers](#🛑-typescript-improvements-for-resolvers)
13+
- [Performance improvements](#performance-improvements)
14+
- [Added new `dataLoader` & `dataLoaderMany` resolvers](#added-new-dataloader--dataloadermany-resolvers)
15+
- [Add `lean: boolean` option to query resolvers](#add-lean-boolean-option-to-query-resolvers)
16+
- [Breaking changes](#breaking-changes)
17+
- [In resolver `updateById` was changed its input args](#in-resolver-updatebyid-was-changed-its-input-args)
18+
- [Some generated types were renamed](#some-generated-types-were-renamed)
19+
- [Misc](#misc)
20+
- [Thanks](#thanks)
21+
- [Thanks to contributors](#thanks-to-contributors)
22+
- [Thanks to sponsors](#thanks-to-sponsors)
23+
24+
<!-- /TOC -->
25+
26+
## What's new?
27+
28+
### 🛑 resolver creation (factory)
29+
30+
- Refactor resolver creation #263
31+
- Expose `mongooseResolvers` for manual creation of resolvers #274
32+
- feat: expose `resolverFactory` for manual resolver creation, eg. for cloned types: `resolverFactory.findMany(UserModel, ClonedUserTC, opts)` – it generates Resolver's types according to `ClonedUserTC` type and will use mongoose `UserModel` for making requests to DB
33+
- feat: added new function `composeMongoose` which generates TypeComposer without resolvers. Now Resolvers can be generated on-demand in such way `PostTC.mongooseResolvers.findMany()` (before was `PostTC.getResolver('findMany')`)
34+
- Improve Typescript definitions for resolvers
35+
36+
### 🛑 error handling (payload.error, mongoose validation)
37+
38+
- Add `error` field & handler for mutations' payload #248
39+
- Resolvers createOne createMany now returns validation errors
40+
41+
## Improvements
42+
43+
### Now `_id` field can be of any type (Int, String, Object)
44+
45+
Before v9.0.0 was supported only `MongoID` type for `_id` field. Now it can be of any type – Int, String, Object. For using this feature you need to add `_id` field to mongoose schema with desired type and graphql-compose-mongoose will do the rest:
46+
47+
```ts
48+
const BookSchema = new mongoose.Schema({
49+
_id: { type: Number },
50+
title: { type: String },
51+
});
52+
53+
interface IBook extends Document {
54+
_id: number;
55+
title?: string;
56+
}
57+
58+
const BookModel = mongoose.model<IBook>('Book', BookSchema);
59+
const BookTC = composeMongoose(BookModel);
60+
```
61+
62+
Notes:
63+
64+
- If you choose type `Number` for `_id` field then `graphql-compose-mongoose` will cast it to `Int` GraphQL type. For other fields `Number` is casted to `Float` by default. Anyway you able change type manually – `BookTC.extendField('_id', { type: 'Float!' })`.
65+
- Be careful: Mongoose will refuse to save a document that doesn't have an `_id`. So you're responsible for setting `_id` if you define your own `_id` path. For automatic numeric id creation you can use the following plugins [mongoose-plugin-autoinc](https://www.npmjs.com/package/mongoose-plugin-autoinc) or [@typegoose/auto-increment](https://www.npmjs.com/package/@typegoose/auto-increment).
66+
67+
[Issue #141](https://github.com/graphql-compose/graphql-compose-mongoose/issues/141)
68+
69+
### 🛑 recursive `filter._operators`
70+
71+
- Adds support for recursive `filter._operators` (rename its type names ) #250
72+
73+
### 🛑 better alias & projection support for nested embedded documents
74+
75+
- Nested projections for embedded documents #273
76+
- feat: nested aliases are now supported for `filter`, `projection` & `lean`
77+
78+
### 🛑 typescript improvements for resolvers
79+
80+
- source is now typed, and first level of available args
81+
82+
## Performance improvements
83+
84+
### Added new `dataLoader` & `dataLoaderMany` resolvers
85+
86+
These resolvers are helpful for relations construction between Entities for avoiding the N+1 Problem via [DataLoader](https://github.com/graphql/dataloader). This problem occurs when a client requests an array of records with some relation data:
87+
- GraphQL call first resolve method with 1 query for getting a list of records
88+
- and for every record will call nested resolve methods which make separate DB requests
89+
90+
As you can expect, doing N+1 queries will flood your database with queries, which is something we can and should avoid. So `dataLoader`, `dataLoaderMany` resolvers make one batch request for getting all related records by id.
91+
92+
```ts
93+
import { schemaComposer } from 'graphql-compose';
94+
import { composeMongoose } from 'graphql-compose-mongoose';
95+
import { mongoose, Document } from 'mongoose';
96+
97+
mongoose.set('debug', true); // <-- show mongoose queries in console
98+
99+
const UserSchema = new mongoose.Schema({
100+
name: { type: String, required: true },
101+
});
102+
const PostSchema = new mongoose.Schema({
103+
title: { type: String, required: true },
104+
authorId: { type: mongoose.Types.ObjectId },
105+
reviewerIds: { type: [mongoose.Types.ObjectId] },
106+
});
107+
108+
interface IUser extends Document {
109+
name: string;
110+
}
111+
112+
interface IPost extends Document {
113+
title: string;
114+
authorId?: mongoose.Types.ObjectId;
115+
reviewerIds?: [mongoose.Types.ObjectId];
116+
}
117+
118+
const UserModel = mongoose.model<IUser>('User', UserSchema);
119+
const PostModel = mongoose.model<IPost>('Post', PostSchema);
120+
121+
const UserTC = composeMongoose(UserModel);
122+
const PostTC = composeMongoose(PostModel);
123+
124+
PostTC.addRelation('author', {
125+
// resolver: () => UserTC.mongooseResolvers.findById({ lean: true }),
126+
resolver: () => UserTC.mongooseResolvers.dataLoader({ lean: true }),
127+
prepareArgs: {
128+
_id: (s) => s.authorId,
129+
},
130+
projection: { authorId: true },
131+
});
132+
133+
PostTC.addRelation('reviewers', {
134+
// resolver: () => UserTC.mongooseResolvers.findByIds({ lean: true }),
135+
resolver: () => UserTC.mongooseResolvers.dataLoaderMany({ lean: true }),
136+
prepareArgs: {
137+
_ids: (s) => s.reviewerIds,
138+
},
139+
projection: { reviewerIds: true },
140+
});
141+
142+
schemaComposer.Query.addFields({
143+
posts: PostTC.mongooseResolvers.findMany(),
144+
});
145+
146+
// console.log(schemaComposer.toSDL());
147+
export const schema = schemaComposer.buildSchema();
148+
```
149+
150+
Test suite for this example can be found [here](https://github.com/graphql-compose/graphql-compose-mongoose/blob/master/src/__tests__/github_issues/260-test.ts).
151+
152+
### Add `lean: boolean` option to query resolvers
153+
154+
Resolvers with `lean: true` is significantly faster than without it (anywhere from 3 - 10 times faster). If you need just `raw` data from DB then use this option. By default queries return fully instantiated Mongoose documents for supporting mongoose's `virtuals` fields, plugins and model methods (but it consume much more CPU & RAM).
155+
156+
`lean` option available in the following resolvers `findById`, `findByIds`, `findMany`, `findOne`, `dataLoader`, `dataLoaderMany`.
157+
158+
BTW mongoose `aliases` are supported with `lean: true` option. graphql-compose-mongoose takes care about their proper conversion in filters, projection and output results:
159+
160+
```ts
161+
// With aliases in MongoDB you will have such records
162+
// { _id: '...', n: 'John', a: 26 }
163+
const AuthorSchema = new mongoose.Schema({
164+
name: { type: String, alias: 'n' },
165+
score: { type: Number, alias: 's' },
166+
});
167+
const AuthorModel = mongoose.model<IAuthor>('Author', AuthorSchema);
168+
169+
// Will be generate graphql type with full field names
170+
// type Author { name: String, score: Float }
171+
const AuthorTC = composeMongoose(AuthorModel, { schemaComposer });
172+
173+
// Resolver will send queries something like that:
174+
// db.author.find({ n: 'John' })
175+
// And convert shortened raw records to full form
176+
// { _id: '...', n: 'John', s: 26 }
177+
const userFindManyResolver = AuthorTC.mongooseResolvers.findMany({ lean: true });
178+
```
179+
180+
- feat add `lean: true` option #259, #266 [commit](https://github.com/graphql-compose/graphql-compose-mongoose/commit/321dded4e2b346e5ab3d549a6bc5b31458478fd1)
181+
182+
## Breaking changes
183+
184+
### In resolver `updateById` was changed its input args
185+
186+
From `UpdateByIdRecord` input type was extracted `_id` field on top level.
187+
188+
```diff
189+
- updateById(record: UpdateByIdRecord!)
190+
+ updateById(_id: MongoID!, record: UpdateByIdRecord!)
191+
```
192+
193+
[Issue #257](https://github.com/graphql-compose/graphql-compose-mongoose/issues/257)
194+
195+
### Some generated types were renamed
196+
197+
- type for `filter._operators` field. Was `OperatorsXXXFilterInput` became `XXXFilterOperatorsInput`. It helps to keep all generated types with the same prefix for `XXX` entity.
198+
- in resolver `count` was changed `filter` type name from `Filter` to `FilterCount`. All rest resolvers already had `FilterFindMany`, `FilterFinOne`, etc. names, and only `count` resolver does not follow this pattern.
199+
200+
## Misc
201+
202+
- Refactor `pagination` & `connection` resolvers (now they are as dependencies) [#272](https://github.com/graphql-compose/graphql-compose-mongoose/issues/272)
203+
- Allow to provide `suffixes` for resolvers configs [#268](https://github.com/graphql-compose/graphql-compose-mongoose/issues/268)
204+
- Remove `getRecordIdFn()` [#262](https://github.com/graphql-compose/graphql-compose-mongoose/issues/262)
205+
206+
## Thanks
207+
208+
### Thanks to contributors
209+
210+
It will not be possible to provide such great improvements in v9.0.0 without the following amazing peoples:
211+
212+
- [Robert Lowe](@RobertLowe) – new improved error payload for Mutations and better validation Errors on document creating/updating.
213+
- [Sean Campbell](natac13) – nested projection for reducing the amount of transmitted data from DB.
214+
- [Morgan Touverey Quilling](@toverux) – non-nullability for fields with default values, help in lean resolvers.
215+
216+
Thank you very much for your help 🙏
217+
218+
### Thanks to sponsors
219+
220+
Special thanks to our sponsors which joined recently:
221+
222+
- **Bruce agency ($250)** – Investing in JAMstack, headless and touchless experiences since 2007, with over 250+ projects built. <https://bruce.agency/>
223+
- **Robert Lowe ($200)** – freelancer with great experience in Realtime web, mobile and desktop apps <http://robertlowe.ca>
224+
225+
And thanks a lot to regular backers – [ScrapeHero](https://www.scrapehero.com/marketplace/) $5,[Woorke](https://woorke.com) $2, [420 Coupon Codes](https://420couponcodes.com/) $2,[ScrapingBee](https://www.scrapingbee.com/) $2, [Adapt.js](https://adaptjs.org/) $2.
226+
227+
Your donations inspire me to improve `graphql-compose` packages. And allow to spend more time on it. Thank you very much for your support!
228+
229+
You may consider to join with sponsoring `graphql-compose` and all its plugins via OpenCollective – https://opencollective.com/graphql-compose

0 commit comments

Comments
 (0)