graphql-compose-mongoose
This is a plugin for graphql-compose, which derives GraphQLType from your mongoose model. 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).
Installation
npm install graphql graphql-compose mongoose graphql-compose-mongoose --save
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.
If you want to add additional resolvers connection
and/or pagination
- just install following packages and graphql-compose-mongoose
will add them automatically.
npm install graphql-compose-connection graphql-compose-pagination --save
Example
Live demo: https://graphql-compose.herokuapp.com/
Source code: https://github.com/nodkz/graphql-compose-mongoose-example
;;; // STEP 1: DEFINE MONGOOSE SCHEMA AND MODELconst LanguagesSchema = language: String skill: type: String enum: 'basic' 'fluent' 'native' ; const UserSchema = name: String // standard types age: type: Number index: true languages: type: LanguagesSchema // you may include other schemas (here included as array of embedded documents) default: contacts: // another mongoose way for providing embedded documents email: String phones: String // array of strings gender: // enum field with values type: String enum: 'male' 'female' 'ladyboy' someMixed: type: mongooseSchemaTypesMixed description: 'Can be any mixed type, that will be treated as JSON GraphQL Scalar Type' ;const UserModel = mongoose; // STEP 2: CONVERT MONGOOSE MODEL TO GraphQL PIECESconst customizationOptions = {}; // left it empty for simplicity, described belowconst UserTC = ; // STEP 3: CREATE CRAZY GraphQL SCHEMA WITH ALL CRUD USER OPERATIONS// via graphql-compose it will be much much easier, with less typingGQC; GQC; const graphqlSchema = GQC;;
That's all! You think that is to much code? 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.
FAQ
Can I get generated vanilla GraphQL types?
const UserTC = ;UserTC; // returns GraphQLObjectTypeUserTC; // returns GraphQLInputObjectType, eg. for argsUserTC; // get GraphQLObjectType for nested fieldUserTC; // get GraphQL type of deep nested field
How to add custom fields?
UserTC
How to build nesting/relations?
Suppose you Model has friendsIds
field with array of user ids. So let build some relations:
UserTC;UserTC;
Reusing the same mongoose Schema in embedded object fields
Suppose you have a common structure you use as embedded object in multiple Schemas. Also suppose you want the structure to have the same GraphQL type across all parent types. (For instance, to allow reuse of fragments for this type) Here are Schemas to demonstrate:
; const ImageDataStructure = ; const UserProfile = ; const Article = ;
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.
Do the following:
;; // Force this type on this mongoose schema
Before continuing to convert your models to TypeComposers:
;; const UserProfileModel = mongoose;const ArticleModel = mongoose; const UserProfileTC = ;const ArticleTC = ;
Then, you can use queries like this:
query { topUser { fullName personalImage { ...fullImageData } } topArticle { title heroImage { ...fullImageData } }}fragment fullImageData on EmbeddedImage { url dimensions { width height }}
Customization options
When we convert model const UserTC = composeWithMongoose(UserModel, customizationOptions);
you may tune every piece of future derived types and resolvers.
Here is flow typed definition of this options:
The top level of customization options. Here you setup name and description for the main type, remove fields or leave only desired fields.
inputType?: typeConverterInputTypeOpts resolvers?: false | typeConverterResolversOpts};
This is opts.inputType
level of options for default InputTypeObject which will be provided to all resolvers for filter
and input
args.
};
This is opts.resolvers
level of options.
If you set the option to false
it will disable resolver or some of its input args.
Every resolver's arg has it own options. They described below.
findOne?: false | filter?: filterHelperArgsOpts | false sort?: sortHelperArgsOpts | false skip?: false findMany?: false | filter?: filterHelperArgsOpts | false sort?: sortHelperArgsOpts | false limit?: limitHelperArgsOpts | false skip?: false updateById?: false | record?: recordHelperArgsOpts | false updateOne?: false | record?: recordHelperArgsOpts | false filter?: filterHelperArgsOpts | false sort?: sortHelperArgsOpts | false skip?: false updateMany?: false | record?: recordHelperArgsOpts | false filter?: filterHelperArgsOpts | false sort?: sortHelperArgsOpts | false limit?: limitHelperArgsOpts | false skip?: false removeById?: false removeOne?: false | filter?: filterHelperArgsOpts | false sort?: sortHelperArgsOpts | false removeMany?: false | filter?: filterHelperArgsOpts | false createOne?: false | record?: recordHelperArgsOpts | false count?: false | filter?: filterHelperArgsOpts | false connection?: false | uniqueFields: string sortValue: mixed directionFilter: <T> T pagination?: false | perPage?: number };
This is opts.resolvers.[resolverName].[filter|sort|record|limit]
level of options.
You may tune every resolver's args independently as you wish.
Here you may setup every argument and override some fields from the default input object type, described above in opts.inputType
.
; // supported operators names in filter `arg`;; ; ; ;
Used plugins
graphql-compose-connection
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).
Besides standard connection arguments first
, last
, before
and after
, also added great arguments:
filter
arg - for filtering recordssort
arg - for sorting records
This plugin completely follows to Relay Cursor Connections Specification.
graphql-compose-pagination
This plugin adds pagination
resolver.