Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wrapResolverResolve does not work with composeMongoose #375

Open
rafaneri opened this issue Sep 5, 2021 · 1 comment
Open

wrapResolverResolve does not work with composeMongoose #375

rafaneri opened this issue Sep 5, 2021 · 1 comment

Comments

@rafaneri
Copy link

rafaneri commented Sep 5, 2021

I'm trying to use wrapResolverResolve for an ObjectTypeComposer created using composeMongoose function, but I get the error:

Error: Type User does not have resolver with name 'createOne'
import { graphql } from 'graphql';
import { Schema, model, connect, connection, disconnect } from 'mongoose';
import { composeMongoose } from 'graphql-compose-mongoose';
import { schemaComposer } from 'graphql-compose';

// STEP 1: DEFINE MONGOOSE SCHEMA AND MODEL
const LanguagesSchema = new Schema({
    language: String,
    skill: {
        type: String,
        enum: ['basic', 'fluent', 'native'],
    },
});

const UserSchema = new Schema({
    name: String, // standard types
    age: {
        type: Number,
        index: true,
    },
    ln: {
        type: [LanguagesSchema], // you may include other schemas (here included as array of embedded documents)
        default: [],
        alias: 'languages', // in schema `ln` will be named as `languages`
    },
    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'],
    },
    someMixed: {
        type: Schema.Types.Mixed,
        description: 'Can be any mixed type, that will be treated as JSON GraphQL Scalar Type',
    },
});
const User = model('User', UserSchema);

// STEP 2: CONVERT MONGOOSE MODEL TO GraphQL PIECES
const customizationOptions = {}; // left it empty for simplicity, described below
const UserTC = composeMongoose(User, customizationOptions);

// STEP 3: ADD NEEDED CRUD USER OPERATIONS TO THE GraphQL SCHEMA
// via graphql-compose it will be much much easier, with less typing
schemaComposer.Query.addFields({
    userById: UserTC.mongooseResolvers.findById(),
    userByIds: UserTC.mongooseResolvers.findByIds(),
    userMany: UserTC.mongooseResolvers.findMany(),
});

schemaComposer.Mutation.addFields({
    userCreateOne: UserTC.mongooseResolvers.createOne(),
    userUpdateOne: UserTC.mongooseResolvers.updateOne(),
});

UserTC.wrapResolverResolve('createOne', next => async rp => {

    // extend resolve params with hook
    rp.beforeRecordMutate = async (doc: any, resolveParams: any) => {
        console.log(doc, resolveParams)
    };

    return next(rp);
});

// STEP 4: BUILD GraphQL SCHEMA OBJECT
const schema = schemaComposer.buildSchema();
export default schema;

// STEP 5: DEMO USE OF GraphQL SCHEMA OBJECT
// Just a demo, normally you'd pass schema object to server such as Apollo server.

(async () => {
    await connect('mongodb://localhost:27017/test');
    await connection.dropDatabase();

    await User.create({ name: 'alice', age: 29, gender: 'female' });
    await User.create({ name: 'maria', age: 31, gender: 'female' });
    const bob = await User.create({ name: 'bob', age: 30, gender: 'male' });

    const response1 = await graphql({
        schema,
        source: 'query { userMany { _id name } }',
    });
    console.dir(response1, { depth: 5 });

    const response2 = await graphql({
        schema,
        source: 'query($id: MongoID!) { userById(_id: $id) { _id name } }',
        variableValues: { id: bob._id },
    });
    console.dir(response2, { depth: 5 });

    const response3 = await graphql({
        schema,
        source: 'mutation($id: MongoID!, $name: String) { userUpdateOne(filter: {_id: $id}, record: { name: $name }) { record { _id name } } }',
        variableValues: { id: bob._id, name: 'bill' },
    });
    console.dir(response3, { depth: 5 });

    disconnect();
})();

But when I use the same but with a composeWithMongoose it works. (example bellow)

import { graphql } from 'graphql';
import { Schema, model, connect, connection, disconnect } from 'mongoose';
import { composeWithMongoose } from 'graphql-compose-mongoose';
import { schemaComposer } from 'graphql-compose';

// STEP 1: DEFINE MONGOOSE SCHEMA AND MODEL
const LanguagesSchema = new Schema({
    language: String,
    skill: {
        type: String,
        enum: ['basic', 'fluent', 'native'],
    },
});

const UserSchema = new Schema({
    name: String, // standard types
    age: {
        type: Number,
        index: true,
    },
    ln: {
        type: [LanguagesSchema], // you may include other schemas (here included as array of embedded documents)
        default: [],
        alias: 'languages', // in schema `ln` will be named as `languages`
    },
    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'],
    },
    someMixed: {
        type: Schema.Types.Mixed,
        description: 'Can be any mixed type, that will be treated as JSON GraphQL Scalar Type',
    },
});
const User = model('User', UserSchema);

// STEP 2: CONVERT MONGOOSE MODEL TO GraphQL PIECES
const customizationOptions = {}; // left it empty for simplicity, described below
const UserTC = composeWithMongoose(User, customizationOptions);

// STEP 3: ADD NEEDED CRUD USER OPERATIONS TO THE GraphQL SCHEMA
// via graphql-compose it will be much much easier, with less typing
schemaComposer.Query.addFields({
    userById: UserTC.getResolver('findById'),
    userByIds: UserTC.getResolver('findByIds'),
    userMany: UserTC.getResolver('findMany'),
});

schemaComposer.Mutation.addFields({
    userCreateOne: UserTC.getResolver('createOne'),
    userUpdateOne: UserTC.getResolver('updateOne'),
});

UserTC.wrapResolverResolve('createOne', next => async rp => {

    // extend resolve params with hook
    rp.beforeRecordMutate = async (doc: any, resolveParams: any) => {
        console.log(doc, resolveParams)
    };

    return next(rp);
});

// STEP 4: BUILD GraphQL SCHEMA OBJECT
const schema = schemaComposer.buildSchema();
export default schema;

// STEP 5: DEMO USE OF GraphQL SCHEMA OBJECT
// Just a demo, normally you'd pass schema object to server such as Apollo server.

(async () => {
    await connect('mongodb://localhost:27017/test');
    await connection.dropDatabase();

    await User.create({ name: 'alice', age: 29, gender: 'female' });
    await User.create({ name: 'maria', age: 31, gender: 'female' });
    const bob = await User.create({ name: 'bob', age: 30, gender: 'male' });

    const response1 = await graphql({
        schema,
        source: 'query { userMany { _id name } }',
    });
    console.dir(response1, { depth: 5 });

    const response2 = await graphql({
        schema,
        source: 'query($id: MongoID!) { userById(_id: $id) { _id name } }',
        variableValues: { id: bob._id },
    });
    console.dir(response2, { depth: 5 });

    const response3 = await graphql({
        schema,
        source: 'mutation($id: MongoID!, $name: String) { userUpdateOne(filter: {_id: $id}, record: { name: $name }) { record { _id name } } }',
        variableValues: { id: bob._id, name: 'bill' },
    });
    console.dir(response3, { depth: 5 });

    disconnect();
})();
@m-lyon
Copy link

m-lyon commented Feb 4, 2024

For those viewing this issue, a workaround is to call the .wrapResolve method on the returned resolver, e.g.

UserTC.mongooseResolvers.createOne().wrapResolve((next) => async (rp) => {

    // extend resolve params with hook
    rp.beforeRecordMutate = async (doc: any, resolveParams: any) => {
        console.log(doc, resolveParams)
    };

    return next(rp);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants