Корневые методы для запросов к подполям GraphQL

1

Я новичок в GraphQL и не знаю, как реализовать запросы в подполе.

Например, скажем, у нас есть следующие типы и запросы:

type Author {
    joinedDate: String,
    quote: String
}

type Post {
    id: String,
    author: Author,
    text: String,
    timeStamp: String,
    location: String
}

type Query {
    posts(authorId: String): [Post]
}

Затем клиенты могут делать такие запросы, как:

// gets everything
{
    posts(authorId: Steve)
}
// just gets time, text, and location
{
    posts(authorId: Steve) {
        timeStamp
        text
        location
    }
}    

Тогда корневой объект можно реализовать следующим образом:

const root = {
    posts: (authorId) => {
        return dataService.getPosts(authorId)
    }
}

Мой вопрос заключается в том, как вы будете внедрять запросы/фильтры в подполе. Например:

// just gets time, text, and location for specific date range
{
    posts(authorId: Steve) {
        timeStamp(minDate: 01012015, maxDate: 10102018)
        text
        location
    }
}

Как определить этот корневой метод? Нужно ли мне фильтровать полный список сообщений вручную в корневом методе posts?

const root = {
    // would this method even have access to the date args?
    posts: (authorId, minDate, maxDate) => {
        const newList = filterTheList(
            dataService.getPosts(authorId),
            minDate,
            maxDate
        )
        return newList
    }
}   

Спасибо за прочтение!

Теги:
graphql
express-graphql

1 ответ

1
Лучший ответ

Если dataService.getPosts() не предоставляет какой-либо способ передать фильтры и вы не можете изменить этот код, то да, вам придется отфильтровать результаты самостоятельно, прежде чем возвращать их в распознаватель.

В противном случае, если dataService просто запрашивает базу данных, вы просто реорганизуете getPosts() чтобы ограничить ваш запрос к базе данных подмножеством на основе переданных ему аргументов.

Если вы пытаетесь ограничить посты возвращаются к определенному диапазону дат, это на самом деле не имеет смысла иметь minDate и maxDate аргументы для поля метки времени. Вместо этого они должны быть аргументами в вашем поле posts как и authorId.

Единственный раз, когда вы должны добавить аргументы в поле, это когда вы хотите изменить поведение этого распознавателя поля. В качестве примера, скажем, у вас есть поле в вашем типе сообщения, как commenters. Список комментариев для сообщения не возвращается как часть списка сообщений, которые вы получаете, вызывая getPosts() - вместо этого вам нужно получить его для каждого сообщения. Если вы хотите отфильтровать или иным образом изменить способ получения или возврата списка комментариев, вы должны добавить один или несколько аргументов в поле commenters.

Чтобы ответить на ваш вопрос более прямо, аргументы, передаваемые вашему резольверу, являются только аргументами для этого конкретного поля - ваш резолвер для posts не получит аргументы для полей под ним.

И последнее, но не менее важное: при написании вашего распознавателя имейте в виду, какие аргументы передаются ему. Если вы используете корневое значение для определения ваших распознавателей, то распознаватель выглядит так:

const root = {
  posts: (args, context, info) => {
    //args.authorId
  }
}

Обратите внимание, что вы получаете один объект для ваших аргументов - они не передаются отдельно для распознавателя.

Когда вы используете корневое значение для определения ваших преобразователей, вы теряете возможность определять преобразователи для полей любых типов, кроме Query, Mutation и Subscription. Я бы посоветовал вам изучить использование graphql-tools в graphql-tools Tools. Это упрощает построение вашей схемы, в то же время предлагая гибкость.

Используя makeExecutableSchema, ваши средства распознавания будут выглядеть так:

const resolvers = {
  Query: {
    posts: (obj, args, context, info) => {}
  },
  Post: {
    someField: (obj, args, context, info) =>{
      //obj here will be the obj a specific Post was resolved to
    }
  }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню