Идеальный дизайн-шаблон для предварительной загрузки и подписки в крупномасштабных веб-приложениях?

Я работаю инженером в крупномасштабном многопользовательском веб-приложении javascript в реальном времени с использованием React и Node. Я хочу перейти на GraphQL/Apollo, чтобы управлять своими данными, изменениями, подписками и т. Д.

В настоящее время я занимаюсь небольшими проектами и начинаю понимать все правильно. Однако возникает вопрос:

  • Существует ли идеальный шаблон проектирования предварительной выборки и подписки в React Apollo для крупномасштабных приложений, в которых изменения могут оказывать влияние в разных местах?

Должны ли запросы и подписки быть связаны только с конкретными компонентами, как я вижу в документе, даже если это означает повторение одних и тех же запросов и подписок для множества компонентов?

Мне известно о кешировании, и тот факт, что метод updateQuery на подписку влияет на все остальные запросы той же формы. Но я иногда работаю в ситуациях, когда обновление запроса также должно обновлять другие запросы другой формы. Позволь мне привести пример:

В Authors.js я получаю список авторов книг и подписываюсь на удаление:

const authorsQuery = gql`
    query {
        authors {
            _id
            name
        }
    }
`

const removeAuthorMutation = gql`
    mutation($_id: ID!) {
        removeAuthor(_id: $_id)
    }
`

const authorRemovedSub = gql`
    subscription {
        authorRemoved
    }
`

export default compose(
    graphql(authorsQuery),
    graphql(removeAuthorMutation)
)(
  class extends React.PureComponent {
    removeAuthor(_id) {
        this.props.mutate({ variables: { _id } })
    }

    componentWillMount() {
        this.props.data.subscribeToMore({
            document: authorRemovedSub,
            updateQuery: (prev, { subscriptionData: { data } }) => {
                if(!data) return prev
                return assign({}, prev, {
                    authors: filter(prev.authors, ({ _id }) => _id !== data.authorRemoved)
                })
            }
        })
    }

    render() {
        ...
    }
})

В Shelf.js я получаю список книг, каждая с определенным автором:

const booksQuery = gql`
    query($shelf: Int!) {
        books(shelf: $shelf) {
            _id
            title
            author {
                _id
                name
            }
        }
    }
`

Когда авторы обновляются в Authors.js, авторы не обновляются в Shelf.js. Согласно документу, кэширование выполняется с помощью поля _id и typename. Поэтому я подскочил, чтобы увидеть, что поле автора соответствующих книг в Shelf.js обнуляется, когда автор удаляется в updateQuery Author.js, но этого не происходит.

Стоит ли подписываться на authorRemoved в Shelf.js и обновлять booksQuery вручную?

Вот моя схема:

type Book {
    _id: ID!
    title: String!
    author: Author
    shelf: Int!
}

type Author {
    _id: ID!
    name: String!
}

type Query {
    authors: [Author!]
    books(shelf: Int!): [Book!]
}

type Mutation {
    registerAuthor(name: String!): Author!
    removeAuthor(_id: ID!): Boolean!
    addBook(title: String!, author: ID, shelf: Int!): Book!
    removeBook(_id: ID!): Boolean!
}

type Subscription {
    authorRegistered: Author!
    authorRemoved: ID!
    bookAdded(shelf: Int!): Book!
    bookRemoved(shelf: Int!): ID!
}

Это одна "проблема". Другой - предварительная выборка. Является ли хорошей идеей предварительная выборка всех данных пользователя (проектов, групп, сообщений и т. Д.) Раз и навсегда, как только он войдет в систему, а затем перейдет только с подписками? Если так, где я должен выполнить эти начальные запросы?

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

Большое спасибо! Оливье

PS: Если вы видите какой-то плохой дизайн в моей схеме, пожалуйста, дайте мне знать.

0 ответов

Другие вопросы по тегам