點燈坊

失くすものさえない今が強くなるチャンスよ

使用 Vue Apollo 建立 Simple Subscription

Sam Xiao's Avatar 2019-12-17

GraphQL Subscription 並不是一定得搭配 GraphQL Query,有時只想單純接收 Subscription 的回傳值,此時可使用 Vue Apollo 所提供的 Simple 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>
    {{ book.title }} / {{ book.price }}
  </div>
</template>

<script>
import gql from 'graphql-tag'

let query = gql`
  subscription {
    bookAdded {
      title
      price
    }
  }
`

let result = function ({ data: { bookAdded } }) {
  this.book = bookAdded
}

export default {
  name: 'app',
  data: () => ({
    book: {}
  }),
  apollo: {
    $subscribe: {
      bookAdded: {
        query,
        result
      }
    }
  }
}
</script>

23 行

export default {
  name: 'app',
  data: () => ({
    book: {}
  }),
  apollo: {
    $subscribe: {
      bookAdded: {
        query,
        result
      }
    }
  }
}

apollo 下新增 $subscribe property,定義 bookAdded subscription,其中包含 queryresult 兩個 property。

  • query:定義 GraphQL subscription
  • result:定義接收 subscription 回傳值的 function

第 10 行

let query = gql`
  subscription {
    bookAdded {
      title
      price
    }
  }
`

定義 bookAdded subscription 的 GraphQL subscription。

19 行

let result = function ({ data: { bookAdded } }) {
  this.book = bookAdded
}

定義接收 bookAdded subscription 回傳值的 result(),可在其 argument 直接 object destruction 解構,然後指定到 data 在 HTML template 顯示。

Browser

simple000

一開始 titleprice 皆沒有資料。

Insomnia

mutation {
  addBook(book: {
    title: "Speaking JavaScript"
    price: 300
  }) {
    title
    price
  }
}

使用 Insomnia 執行 addBook mutation,相當於在其他 client 執行 mutation 觸發 subscription。

smart001

Browser

simple002

立即顯示 bookAdded subscription 所回傳資料。

Conclusion

  • 只要在 apollo 下的 $subscribe 定義 subscription 後,再分別定義 queryresult(),就能簡單的接收到 GraphQL subscription 的回傳值
  • 之後若有新的 subscription 但回傳不同值,Vue 也能及時更新,不必再使用 polling 方式

Sample Code

完整範例可在我的 GitHub 上找到

Reference

Vue Apollo, Simple Subscription