You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[](https://gitter.im/graphql-compose/Lobby)
This is a plugin for [graphql-compose](https://github.com/graphql-compose/graphql-compose), which derives GraphQLType from your [mongoose model](https://github.com/Automattic/mongoose). Also derives bunch of internal GraphQL Types. Provide all CRUD resolvers, including `graphql connection`, also provided basic search via operators ($lt, $gt and so on).
Modules `graphql`, `graphql-compose`, `mongoose` are in `peerDependencies`, so should be installed explicitly in your app. They have global objects and should not have ability to be installed as submodule.
19
20
20
21
If you want to add additional resolvers [`connection`](https://github.com/graphql-compose/graphql-compose-connection) and/or [`pagination`](https://github.com/graphql-compose/graphql-compose-pagination) - just install following packages and `graphql-compose-mongoose` will add them automatically.
-`UserTC` - this is a `TypeComposer` instance for User. `TypeComposer` has `GraphQLObjectType` inside, avaliable via method `UserTC.getType()`.
48
-
- Here and in all other places of code variables suffix `...TC` means that this is `TypeComposer` instance, `...ITC` - `InputTypeComposer`, `...ETC` - `EnumTypeComposer`.
52
+
-`UserTC` - this is a `ObjectTypeComposer` instance for User. `ObjectTypeComposer` has `GraphQLObjectType` inside, avaliable via method `UserTC.getType()`.
53
+
- Here and in all other places of code variables suffix `...TC` means that this is `ObjectTypeComposer` instance, `...ITC` - `InputTypeComposer`, `...ETC` - `EnumTypeComposer`.
I don't think so, because by default internally was created about 55 graphql types (for input, sorting, filtering). So you will need much much more lines of code to implement all these CRUD operations by hands.
124
130
125
-
126
131
### Working with Mongoose Collection Level Discriminators
132
+
127
133
Variable Namings
128
-
*`...DTC` - Suffix for a `DiscriminatorTypeComposer` instance, which is also an instance of `TypeComposer`. All fields and Relations manipulations on this instance affects all registered discriminators and the Discriminator Interface.
134
+
135
+
-`...DTC` - Suffix for a `DiscriminatorTypeComposer` instance, which is also an instance of `ObjectTypeComposer`. All fields and Relations manipulations on this instance affects all registered discriminators and the Discriminator Interface.
Suppose you `User` model has `friendsIds` field with array of user ids. So let build some relations:
286
+
276
287
```js
277
288
UserTC.addRelation(
278
289
'friends',
@@ -305,10 +316,12 @@ UserTC.addRelation(
305
316
```
306
317
307
318
### Reusing the same mongoose Schema in embedded object fields
319
+
308
320
Suppose you have a common structure you use as embedded object in multiple Schemas.
309
321
Also suppose you want the structure to have the same GraphQL type across all parent types.
310
322
(For instance, to allow reuse of fragments for this type)
311
323
Here are Schemas to demonstrate:
324
+
312
325
```js
313
326
import { Schema } from'mongoose';
314
327
@@ -330,16 +343,20 @@ const Article = Schema({
330
343
heroImage: ImageDataStructure
331
344
});
332
345
```
346
+
333
347
If you want the `ImageDataStructure` to use the same GraphQL type in both `Article` and `UserProfile` you will need create it as a mongoose schema (not a standard javascript object) and to explicitly tell `graphql-compose-mongoose` the name you want it to have. Otherwise, without the name, it would generate the name according to the first parent this type was embedded in.
334
348
335
349
Do the following:
350
+
336
351
```js
337
352
import { schemaComposer } from'graphql-compose'; // get the default schemaComposer or your created schemaComposer
@@ -375,16 +394,18 @@ fragment fullImageData on EmbeddedImage {
375
394
```
376
395
377
396
### Access and modify mongoose doc before save
397
+
378
398
This library provides some amount of ready resolvers for fetch and update data which was mentioned above. And you can [create your own resolver](https://github.com/graphql-compose/graphql-compose) of course. However you can find that add some actions or light modifications of mongoose document directly before save at existing resolvers appears more simple than create new resolver. Some of resolvers accepts *before save hook* which can be provided in *resolver params* as param named `beforeRecordMutate`. This hook allows to have access and modify mongoose document before save. The resolvers which supports this hook are:
### How can I push/pop or add/remove values to arrays?
469
+
447
470
The default resolvers, by design, will replace (overwrite) any supplied array object when using e.g. `updateById`. If you want to push or pop a value in an array you can use a custom resolver with a native MongoDB call.
`User` is the corresponding Mongoose model. If you do not wish to allow duplicates in the array then replace `$push` with `$addToSet`. Read the graphql-compose docs on custom resolvers for more info: https://graphql-compose.github.io/docs/en/basics-resolvers.html
469
492
470
493
NB if you set `unique: true` on the array then using the `update``$push` approach will not check for duplicates, this is due to a MongoDB bug: https://jira.mongodb.org/browse/SERVER-1068. For more usage examples with `$push` and arrays see the MongoDB docs here https://docs.mongodb.com/manual/reference/operator/update/push/. Also note that `$push` will preserve order in the array (append to end of array) whereas `$addToSet` will not.
471
494
472
-
473
495
## Customization options
474
496
475
497
When we convert model `const UserTC = composeWithMongoose(User, customizationOptions);` you may tune every piece of future derived types and resolvers.
476
498
477
499
### Here is flow typed definition of this options:
478
500
479
501
The top level of customization options. Here you setup name and description for the main type, remove fields or leave only desired fields.
502
+
480
503
```js
481
504
exporttypetypeConverterOpts= {
482
505
name?: string,
@@ -491,6 +514,7 @@ export type typeConverterOpts = {
491
514
```
492
515
493
516
This is `opts.inputType` level of options for default InputTypeObject which will be provided to all resolvers for `filter` and `input` args.
517
+
494
518
```js
495
519
exporttypetypeConverterInputTypeOpts= {
496
520
name?: string,
@@ -506,6 +530,7 @@ export type typeConverterInputTypeOpts = {
506
530
This is `opts.resolvers` level of options.
507
531
If you set the option to `false` it will disable resolver or some of its input args.
508
532
Every resolver's arg has it own options. They described below.
533
+
509
534
```js
510
535
exporttypetypeConverterResolversOpts= {
511
536
findById?: false,
@@ -571,6 +596,7 @@ export type typeConverterResolversOpts = {
571
596
This is `opts.resolvers.[resolverName].[filter|sort|record|limit]` level of options.
572
597
You may tune every resolver's args independently as you wish.
573
598
Here you may setup every argument and override some fields from the default input object type, described above in `opts.inputType`.
599
+
574
600
```js
575
601
exporttypefilterHelperArgsOpts= {
576
602
filterTypeName?: string, // type name for `filter`
@@ -604,16 +630,20 @@ export type limitHelperArgsOpts = {
This plugin adds `connection` resolver. Build in mechanism allows sort by any unique indexes (not only by id). Also supported compound sorting (by several fields).
608
635
609
636
Besides standard connection arguments `first`, `last`, `before` and `after`, also added great arguments:
610
-
*`filter` arg - for filtering records
611
-
*`sort` arg - for sorting records
637
+
638
+
-`filter` arg - for filtering records
639
+
-`sort` arg - for sorting records
612
640
613
641
This plugin completely follows to [Relay Cursor Connections Specification](https://facebook.github.io/relay/graphql/connections.htm).
0 commit comments