株式会社iCAREのプロダクトCarelyのフロントエンド環境は、Vue.js + GraphQL(Vue Apolloを利用)で構成されています。
Carelyでは、今絶賛、Option APIからComposition APIへの移行中です。
その中でVue Apolloに関しても、Composition APIに合わせて、Vue Apollo v3から@vue/apollo-composable(Vue Apollo v4)に移行していますが、そこでどのように変わるのか、どんなメリットが生じるかについて書きたいと思います。
情報ソースは主に以下を利用しています。
https://apollo.vuejs.org/guide/
https://v4.apollo.vuejs.org/guide-composable/
これから移行を検討しているエンジニアの皆様の参考になれば幸いです。
クエリの書き方
v3の場合
apollo: {
users: gql`
query getUsers {
users {
id
name
}
}
`,
},
のように「オプション」でクエリを定義すると、テンプレートでクエリの結果users
を参照することができます。
この際、クエリの結果をusers
で参照するためには
data () {
return {
users: [],
},
},
のようにdata
オプション内でusers
を初期化しておく必要があります。
v4の場合
<script>
import { useQuery } from '@vue/apollo-composable'
import gql from 'graphql-tag'
export default {
setup () {
const { result } = useQuery(gql`
query getUsers {
users {
id
name
}
}
`)
return {
result,
}
},
}
</script>
オプションではなく、useQuery
関数を使ってクエリを実行します。
setup()
の戻り値にresult
を含めることでテンプレートからresult
を参照できます。
v3と異なりクエリの結果を受け取る変数を事前に、data
オプションで初期化する必要はありません。
<template>
<ul>
<li v-for="user of result.users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template>
v3とv4で大きく異なる点(主観)
マルチルートのクエリへの対応
query getCatsAndDogs {
cats {
id
}
dogs {
id
}
}
といったクエリの結果を受け取る場合、v3の場合は、クエリの結果が自動的にdata
オプションで指定したオブジェクトのプロパティにマップされるため、デフォルトではこの結果をうまく受け取ることができません。
v4の場合は、マルチルートの結果は、useQuery
の戻り値のプロパティとして受け取ることができるため、特段の迂回策を取らずに受け取ることができます。
useResult
v4にはuseQuery
と並んでuseResult
があり、クエリ結果に対して柔軟にアクセスすることができるようになっています。
const { result } = useQuery(gql`
query getMessages {
currentUser {
messages {
id
text
}
}
}
`)
const messages = useResult(result, null, data => data.currentUser.messages)
上記のようにuseResult
を使って結果を取得した場合、result.values
がundefined
だとしても、useResult
の関数の中でエラーが出ないように実装されているので
const messages = useResult(result, null, data => data && data.currentUser && data.currentUser.messages)
のように子要素の存在チェックをする必要はありません。
また、この様に簡単に処理を分けることもできます。
import { useQuery } from '@vue/apollo-composable'
import gql from 'graphql-tag'
function useGetMessages() {
const { result } = useQuery(gql`
query getMessages {
currentUser {
messages {
id
text
}
}
}
`)
return useResult(result, null, data => data.currentUser.messages)
}
export default {
setup () {
const messages = useGetMessages()
return { messages }
}
}
その他にも様々な点での仕様の変更があり、v3と比較してv4はいろいろな点で使いやすくなっている印象を受けました。
参考サイト
https://apollo.vuejs.org/guide/
https://v4.apollo.vuejs.org/guide-composable/