GraphQL Subscription 最常使用的場景為原本 Smart Query 已經有資料,但經過 Subscription 通知後需更新原本資料,Vue Apollo 特別設計了 Smart Subscription,可在完全不知道 WebSocket 前提下,不知不覺使用 GraphQL Subscription。
Version
macOS Catalina 10.15.2
WebStorm 2019.3
Node 13.2.0
Vue CLI 4.1.1
Vue 2.6.10
Vue Apollo 3.0.0-beta.11
Vue Apollo
src/App.vue
<template>
<div>
<ul>
<li v-for="(item, index) in books" :key="index">
{{ item.title }}:{{ item.price }}
</li>
</ul>
</div>
</template>
<script>
import gql from 'graphql-tag'
let query = gql`
query {
books {
title
price
}
}
`
let document = gql`
subscription {
bookAdded {
title
price
}
}
`
let updateQuery = ({ books }, { subscriptionData: { data: { bookAdded } } }) => ({
books: [...books, bookAdded]
})
let books = {
query,
subscribeToMore: {
document,
updateQuery
}
}
export default {
name: 'app',
apollo: {
books
}
}
</script>
44 行
export default {
name: 'app',
apollo: {
books
}
}
在 apollo
property 下定義 books
smart query。
第 3 行
<ul>
<li v-for="(item, index) in books" :key="index">
{{ item.title }}:{{ item.price }}
</li>
</ul>
在 HTML template 內可直接使用 v-for
搭配 books
smart query。
39 行
let books = {
query,
subscribeToMore: {
document,
updateQuery
}
}
實踐 books
smart query,原本只需定義 query
property 即可,若還需 smart subscription,則還需定義 subscribeToMore
property,其為 object,包含 document
與 updateQuery
兩個 property。
- query:定義 GraphQL query
- document:定義 GraphQL subscription
- updateQuery:定義當 subscription 觸發時須執行的 function
14 行
let query = gql`
query {
books {
title
price
}
}
`
定義 books
smart query 的 GraphQL query。
23 行
let document = gql`
subscription {
bookAdded {
title
price
}
}
`
定義 books
smart subscription 的 GraphQL subscription。
32 行
let updateQuery = ({ books }, { subscriptionData: { data: { bookAdded } } }) => ({
books: [...books, bookAdded]
})
定義 books
smart subscription 被觸發時所要執行的 function。
第一個 argument 為原本 books
smart query 的資料。
第二個 argument 為 subscription 所回傳資料。
兩者都可使用 ES6 的 object destructuring 直接解構,最後再使用 array spread 組合成最新資料回傳。
Browser
原本 books
smart query 只有 2
筆資料。
Insomnia
mutation {
addBook(book: {
title: "Speaking JavaScript"
price: 300
}) {
title
price
}
}
使用 Insomnia 執行 addBook
mutation,相當於在其他 client 執行 mutation 觸發 subscription。
Browser
原本 books
smart query 自動更新成 3
筆資料。
Conclusion
- Vue Apollo 讓我在收到 GraphQL subscription 後,不用再重新執行 GraphQL Query,只要實踐
updateQuery()
即可自動在背景更新原本資料,非常方便
Sample Code
完整範例可在我的 GitHub 上找到