Nuxt x Composition API x Hasura x TypeScriptを実装する
まずはHasura Cloudでプロジェクトを作っておきましょう
接続に必要なGraphQLのAPIエンドポイントと、アクセス時にヘッダーに必要なAdmin Secretを控えておきます
次にNuxtプロジェクトをnpxで作ります
$ npx create-nuxt-app nuxt-composable-hasura
次に必要なライブラリ群をインストールしていきましょう(各ライブラリの導入に必要なnuxt.config.js
への設定はここでは省きます)
まずNuxtでcomposition APIを使うためのライブラリを入れます
次に「Nuxt内で」且つ、「Composable APIで」、apolloを使うためのライブラリを2つ入れます
そして、@nuxtjs/apollo
で設定したApollo Clientを、プラグインという形でApollo Composableから呼び出せるよう登録します
// nuxt.config.jsのapolloで、先程取得したHasura情報をセットして
apollo: {
clientConfigs: {
default: {
httpEndpoint: process.env.GRAPHQL_ENDPOINT,
httpLinkOptions: {
headers: {
'X-Hasura-Admin-Secret': process.env.HASURA_SECRET,
},
},
},
},
}
// 今作ったApollo ClientをDefaultApolloClientとして登録する
import { Plugin } from '@nuxt/types'
import { provide, onGlobalSetup } from '@nuxtjs/composition-api'
import { DefaultApolloClient } from '@vue/apollo-composable'
const ApolloPlugin: Plugin = ({ app }) => {
onGlobalSetup(() => {
provide(DefaultApolloClient, app.apolloProvider.defaultClient)
})
}
export default ApolloPlugin
// pluginの登録を忘れずに
plugins: ['@/plugins/apollo'],
お次は、graphqlをTypeScriptから使うために、graphql-codegenのライブラリを入れていきます
自分の場合、環境変数を使いたいのでcodegen.js
でdotenvを呼び出す形で設定しています
require('dotenv').config()
module.exports = {
overwrite: true,
schema: [
{
[process.env.GRAPHQL_ENDPOINT]: {
headers: {
'x-hasura-admin-secret': process.env.HASURA_SECRET,
},
},
},
],
documents: ['./src/**/*.{graphql,gql}'],
generates: {
'./src/generated/graphql.ts': {
plugins: ['typescript', 'typescript-operations', 'typed-document-node'],
},
'./graphql.schema.json': {
plugins: ['introspection'],
},
},
}
このファイルがプロジェクトルート直下にある状態でと、スキーマファイルと、TypeScript向けのファイルが発行されます
あとは実際に使うスクリプトを設定して
query getUsers {
users(order_by: { id: asc }) {
id
name
}
}
yarn gql-gen
を実行します。
するとsrc/generated/graphql.ts
というファイルで、TypeScriptの型付きのファイルが発行されます(getUsersというクエリは、GetUsersDocument
というDocumentNode
型に変換されます)
これを@vue/apollo-composable
から呼び出します
<template>
<div>
<ul>
<li v-for="user in users" :key="user.id">{{ user.name }}</li>
</ul>
</div>
</template>
<script lang="ts">
import { defineComponent } from '@vue/composition-api'
import { GetUsersDocument } from '@/generated/graphql'
import { useQuery, useResult } from '@vue/apollo-composable'
export default defineComponent({
name: 'IndexPage',
setup() {
const { result } = useQuery(GetUsersDocument)
const users = useResult(result, [], (data) => data?.users)
return { users }
},
})
</script>
mutationも同様に実装できます(細かい@vue/apollo-composable
の使い方は、公式のドキュメントに任せます)
今回のコードはこんな感じ
Discussion