2017-02-22 17 views
0

Кажется, что я не получаю что-то фундаментальное с графиком.graphql throws неизвестный аргумент error

Я пытаюсь получить пользователя по его идентификатору, который в свою очередь является результатом другого запроса. В этом случае запрос на некоторые данные сеанса.

Я не понимаю, почему возникает ошибка.

Вот мой код:

{ 
    session(key: "558fd6c627267d737d11e758f1ae48cae71fc9b584e2882926ad5470c88d7c3ace08c9c7") { 
     userId 
     expires 
     user(id: userId) { 
      name 
     } 
    } 
} 

И я получаю

Неизвестный аргумент "ID" на поле "пользователь" типа "Session"

Моя схема выглядит следующим образом:

type Session { 
    userId: String, 
    expires: String, 
    user: User 
} 

type User { 
    _id: String 
    name: String 
    email: String 
    firstName: String 
    lastName: String 
} 

type Query { 
    session(key: String!): Session 
    user(id: String!): User 
} 

Добавление 23 февраля 2017 года

Прошу прощения за то, что я не был достаточно явным в отношении соответствующих резольверов в своем первоначальном сообщении. Да, я определил свои решители и д. г. запрос работает для сеанса, если я не добавляю пользователей.

Вот мой корень:

{ 
    Query: { 
     async user(parentValue, args, req) { 
      let user = await adapters.users.byId(args.id); 
      return user; 
     }, 
     async session(parentValue, args, req) { 
      let session = await adapters.session(args.key); 
      let userId = session.session.userId; 
      let expires = session.expires; 
      return {userId: userId, expires: expires}; 
     } 
    } 

} 

ответ

0

Вам нужно создать некоторую resolver функцию на поле user в типе Session, потому что GraphQL не знает, как вернуть user. В graphql-js это будет выглядеть, что

const Session = new GraphQLObjectType({ 
    name: 'Session', 
    fields: { 
     userId: { type: GraphQLString }, 
     expires: { type: GraphQLString }, 
     user: { 
      type: User, // it is your GraphQL type 
      resolve: function(obj, args, context){ 
       // obj is the session object returned by ID specified in the query 
       // it contains attributes userId and expires 
       // however graphql does not know you want to use the userId in order to retrieve user of this session 
       // that is why you need to specify the value for field user in type Session 
       return db.User.findById(obj.userId).then(function(user){ 
        return user; 
       }); 
      } 
     } 
    } 
}); 

Это лишь простой пример из Node.js, чтобы показать вам, как вы могли бы вернуть экземпляр user. У вас есть возможность указать, как извлекать значения каждого поля в каждом типе GraphQL (каждое поле может иметь собственную функцию resolve).

Я предлагаю вам прочитать документацию GraphQL относительно root and resolvers

EDIT

Я покажу вам пример, как можно справиться с такой ситуацией. Рассмотрим два типа: User и Session

type User { 
    _id: String 
    name: String 
} 

type Session { 
    expires: String 
    user: User 
} 

Если вы хотите, чтобы ваш запрос, чтобы вернуть Session объект вместе с его User, вам не нужно включать userId поле в Session типа. Вы можете решить эту ситуацию двумя способами. Сначала нужно использовать единый резольвер для запроса session.

{ 
    Query: { 
     async session(parentValue, args, req) { 
      let session = await adapters.session(args.key); 
      // now you have your session object with expires and userId attributes 
      // in order to return session with user from query, you can simply retrieve user with userId 
      let user = await adapter.users.byId(session.userId); 
      return { expires: session.expires, user: user } 
     } 
    } 
} 

Это ваш первый вариант. С помощью этого решения вы можете вернуть объект session с назначенным ему user одним запросом и без дополнительных resolve методов на любые поля Session типа.Второе решение - это тот, который я показал ранее, когда вы используете метод resolve в поле user из Session типа - поэтому вы просто указываете GraphQL, как он должен получить значение для этого поля.

+0

Хорошо, я виноват, я думал, что для каждого запроса есть резольверы. Если бы у меня не было резольверов, программа даже сработала бы до этого сообщения об ошибке. Но ради полноты и экспликации я добавлю свои резольверы в код выше. Запрос работает, если я просто запрашиваю сеанс без пользователя. Еще одна вещь: я использую инструменты Graphql для Apollo для определения схемы, поэтому это определение основано на языке типа GraphQL. Взгляните на добавление с 23 февраля 2017 года – LongHike

+0

Я отредактировал ответ, чтобы привести пример для вашего дела – piotrbienias

+0

Большое спасибо. Это работает! – LongHike