Как создать вложенный резольвер в сервере apollo graphql

Учитывая следующую графическую схему сервера apollo Я хотел разбить их на отдельные модули, поэтому мне не нужен запрос автора в корневой схеме запроса.. и хочу, чтобы он был разделен. Поэтому я добавил еще один слой с именем authorQueries перед добавлением его в Root Query

type Author {
    id: Int,
    firstName: String,
    lastName: String
}  
type authorQueries {
    author(firstName: String, lastName: String): Author
}

type Query {
    authorQueries: authorQueries
}

schema {
    query: Query
}

Я попробовал следующее: вы можете видеть, что authorQueries был добавлен как другой слой до того, как указана функция автора.

Query: {
    authorQueries :{
        author (root, args) {
            return {}
       }
    }
}

При запросе в Graphiql я добавил также дополнительный слой.

{
    authorQueries {
        author(firstName: "Stephen") {
            id
        }
    }
}

Я получаю следующую ошибку.

"message": "Resolve function for \"Query.authorQueries\" returned undefined",

Ответ 1

Чтобы создать "вложенный" резольвер, просто определите распознаватель для возвращаемого типа родительского поля. В этом случае ваше поле authorQueries возвращает тип authorQueries, поэтому вы можете поместить там свой резольвер:

{
  Query: { authorQueries: () => ({}) },
  authorQueries: {
    author(root, args) {
      return "Hello, world!";
    }
  }
}

Таким образом, в техническом смысле нет такой вещи, как вложенный резольвер - каждый тип объекта имеет плоский список полей, и эти поля имеют возвращаемые типы. Вложенность запроса GraphQL является тем, что делает результат вложенным.

Ответ 2

Я обнаружил, что возвращение функций в родительских полях, возвращающих тип, приводит к связыванию this аргумента и нарушает интерфейс распознавателя, поскольку вложенный преобразователь не является родительским в качестве первого аргумента.

Для встроенных определений типов

import {
  graphql,
} from 'graphql';

import {
  makeExecutableSchema, IResolverObject
} from 'graphql-tools';

const types = '
type Query {
  person: User
}

type User {
  id: ID
  name: String,
  dog(showCollar: Boolean): Dog
}

type Dog {
  name: String
}
';

const User: IResolverObject = {
  dog(obj, args, ctx) {
    console.log('Dog Arg 1', obj);
    return {
      name: 'doggy'
    };
  }
};

const resolvers = {
  User,
  Query: {
    person(obj) {
      console.log('Person Arg 1', obj);
      return {
        id: 'foo',
        name: 'bar',
      };
    }
  }
};

const schema = makeExecutableSchema({
  typeDefs: [types],
  resolvers
});

const query = '{ 
  person {
    name,
    dog(showCollar: true) {
      name
    }
  }
 }';


graphql(schema, query).then(result => {
  console.log(JSON.stringify(result, null, 2));
});

// Person Arg 1 undefined
// Dog Arg 1 { id: 'foo', name: 'bar' }
// {
//   "data": {
//     "person": {
//       "name": "bar",
//       "dog": {
//         "name": "doggy"
//       }
//     }
//   }
// }

Вы также можете использовать addResolveFunctionsToSchema как показано ниже.

https://gist.github.com/blugavere/4060f4bf2f3d5b741c639977821a254f

Ответ 3

Я также сталкиваюсь с такой проблемой, но все еще не могу решить в моем конце. Любые входы будут полезны.

Я подал ошибку на graphql-tools на github, но пока не получил ответа.

https://github.com/apollographql/graphql-tools/issues/1026.

Привет команда,

Вложенные поля моей схемы не вызываются во время запроса.

схема

type XYZ {
   title: String
}

type NestedLevel1 {
   reference: XYZ
}

type ABCD {
   title: String
   reference: XYZ
   nestedLevel1: NestedLevel1 
}

type Query {
     ABCDList(limit: Int, skip: Int): [ABCD]
}

//Resolvers

const Resolvers = {
    Query: {
        ABCDList: () => []
    },
    ABCD: {
        reference: () => [] // this function is being called
        nestedLevel1: {
            reference: () => [] // this function is not being called
        }
    }
}

Вызывается функция резолвера "reference" верхнего уровня, но не решатель nestedLevel1.reference.