我們是基於 websocket 的訂閱模式,所以需要做一些配置
$ yarn add apollo-link-ws apollo-utilities
可以根據官網給的範例直接做配置
// New Imports
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { split } from 'apollo-link'
import { WebSocketLink } from 'apollo-link-ws'
import { getMainDefinition } from 'apollo-utilities'
export function createProvider (options = {}) {
const httpLink = new HttpLink({
// You should use an absolute URL here
uri: 'http://localhost:4000/graphql',
})
// Create the subscription websocket link
const wsLink = new WebSocketLink({
uri: 'ws://localhost:4000/graphql',
options: {
reconnect: true,
timeout: 30000
},
})
// using the ability to split links, you can send data to each link
// depending on what kind of operation is being sent
const link = split(
// split based on operation type
({ query }) => {
const definition = getMainDefinition(query)
return definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
},
wsLink,
httpLink
)
// Create the apollo client
const apolloClient = new ApolloClient({
link,
cache: new InMemoryCache(),
connectToDevTools: true,
})
// Create vue apollo provider
const apolloProvider = new VueApollo({
defaultClient: apolloClient,
defaultOptions: {
$query: {
// fetchPolicy: 'cache-and-network',
},
},
errorHandler (error) {
// eslint-disable-next-line no-console
console.log('%cError', 'background: red; color: white; padding: 2px 4px; border-radius: 3px; font-weight: bold;', error.message)
},
})
return apolloProvider
}
開始編寫 Schema
我們的流程是,當新增一筆 comment 後,所有訂閱者都能收到 comment
所以這邊我們會有一個 mutation 以及 subscription,由 mutation 觸發 subscription 進行廣播。
export const COMMENT_ADDED = gql`
subscription commentAdded ($title: String!){
commentAdded(title: $title) {
title
comment
}
}
`
export const ADD_COMMENT = gql`
mutation addComment ($title: String!, $comment: String!){
addComment(title: $title, comment: $comment) {
comment
}
}
`
使用簡單的訂閱模式 $subscribe ,可以直接取得結果
如果想更新 apollo 查詢結果,可以使用另一種模式 Smart Subscriptions ,他提供了 subscribeToMore ,可讓查詢的 API 取得訂閱的結果,直接更新查詢結果並回傳
methods: {
async addComment() {
const response = await this.$apollo.mutate({
mutation: ADD_COMMENT,
variables: {
title: "title",
comment: this.comment
}
})
}
},
apollo: {
authors: {
query: AUTHORS
},
$subscribe: {
commentAdded: {
query: COMMENT_ADDED,
variables: {
title: "title"
},
result ({ data }) {
this.comments.push(data.commentAdded);
},
}
}
}
給予一個輸入框可以輸入 comment ,以及一個按鈕觸發事件
<template>
<div>
<v-text-field v-model="comment"></v-text-field>
<v-btn @click="addComment">addComment</v-btn>
<div v-for="item in comments" :key="item.id">
{{item.comment}}
</div>
</div>
</template>
完成後就能來進行測試,打開兩個瀏覽器
當其中一邊送出 comment 後,兩個瀏覽器都能收到 comment
左邊輸入文字,右邊也能收到,這就是 Subscription 功能
生活中常用的案例就是聊天系統,讀者可以將頁面完善,做一個簡易型的聊天室!